solutions/zokrates_prover/.zokrates/stdlib/signatures/verifyEddsa.zok

52 lines
2.0 KiB
Plaintext
Executable File

import "hashes/sha256/1024bitPadded" as sha256;
import "ecc/edwardsScalarMult" as scalarMult;
import "ecc/edwardsAdd" as add;
import "utils/pack/bool/nonStrictUnpack256" as unpack256bool;
import "utils/pack/u32/nonStrictUnpack256" as unpack256u;
import "ecc/edwardsOnCurve" as onCurve;
import "ecc/edwardsOrderCheck" as orderCheck;
from "ecc/babyjubjubParams" import BabyJubJubParams;
import "utils/casts/u32_8_to_bool_256";
/// Verifies an EdDSA Signature.
///
/// Checks the correctness of a given EdDSA Signature (R,S) for the provided
/// public key A and message (M0, M1).
/// This python repo provides the tooling for creating valid signatures:
/// https://github.com/Zokrates/pycrypto
///
/// For more information see:
/// https://en.wikipedia.org/wiki/EdDSA
/// https://eprint.iacr.org/2015/677.pdf
///
/// Arguments:
/// R: Curve point. Hidden version of the per-message nonce.
/// S: Field element. Signature to be verified.
/// A: Curve point. Public part of the key used to create S.
/// M0: 256bit array. First 256bits of the message used to create S .
/// M1: 256bit array. Trailing 256bits of the message used to create S .
/// context: Curve parameters used to create S.
///
/// Returns:
/// Return true for S being a valid EdDSA Signature, false otherwise.
def main(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1, BabyJubJubParams context) -> bool {
field[2] G = [context.Gu, context.Gv];
// Check if R is on curve and if it is not in a small subgroup. A is public input and can be checked offline
assert(onCurve(R, context)); // throws if R is not on curve
assert(orderCheck(R, context));
u32[8] Rx = unpack256u(R[0]);
u32[8] Ax = unpack256u(A[0]);
bool[256] hRAM = u32_8_to_bool_256(sha256(Rx, Ax, M0, M1));
bool[256] sBits = unpack256bool(S);
field[2] lhs = scalarMult(sBits, G, context);
field[2] AhRAM = scalarMult(hRAM, A, context);
field[2] rhs = add(R, AhRAM, context);
bool out = rhs[0] == lhs[0] && rhs[1] == lhs[1];
return out;
}