int ed25519_donna_blind_public_key(unsigned char *out, const unsigned char *inp, const unsigned char *param) { static const bignum256modm zero = { 0 }; unsigned char tweak[64]; unsigned char pkcopy[32]; ge25519 ALIGN(16) A, Aprime; bignum256modm ALIGN(16) t; ed25519_donna_gettweak(tweak, param); expand256_modm(t, tweak, 32); /* No "ge25519_unpack", negate the public key. */ memcpy(pkcopy, inp, 32); pkcopy[31] ^= (1<<7); ge25519_unpack_negative_vartime(&A, pkcopy); /* A' = [tweak] * A + [0] * basepoint. */ ge25519_double_scalarmult_vartime(&Aprime, &A, t, zero); ge25519_pack(out, &Aprime); memwipe(tweak, 0, sizeof(tweak)); memwipe(pkcopy, 0, sizeof(pkcopy)); memwipe(&A, 0, sizeof(A)); memwipe(&Aprime, 0, sizeof(Aprime)); memwipe(t, 0, sizeof(t)); return 0; }
int crypto_sign_open( unsigned char *m,unsigned long long *mlen, const unsigned char *sm,unsigned long long smlen, const unsigned char *pk ) { unsigned char pkcopy[32]; unsigned char rcopy[32]; unsigned char hram[64]; unsigned char rcheck[32]; ge25519 get1, get2; sc25519 schram, scs; if (smlen < 64) goto badsig; if (sm[63] & 224) goto badsig; if (ge25519_unpackneg_vartime(&get1,pk)) goto badsig; memmove(pkcopy,pk,32); memmove(rcopy,sm,32); sc25519_from32bytes(&scs, sm+32); memmove(m,sm,smlen); memmove(m + 32,pkcopy,32); crypto_hash_sha512(hram,m,smlen); sc25519_from64bytes(&schram, hram); ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs); ge25519_pack(rcheck, &get2); if (crypto_verify_32(rcopy,rcheck) == 0) { memmove(m,m + 64,smlen - 64); memset(m + smlen - 64,0,64); *mlen = smlen - 64; return 0; } badsig: *mlen = (unsigned long long) -1; memset(m,0,smlen); return -1; }
int crypto_sign_ed25519_open( unsigned char *m,unsigned long long *mlen, const unsigned char *sm,unsigned long long smlen, const unsigned char *pk ) { unsigned int i; int ret; unsigned char t2[32]; ge25519 get1, get2; sc25519 schram, scs; unsigned char hram[crypto_hash_sha512_BYTES]; *mlen = (unsigned long long) -1; if (smlen < 64) return -1; if (ge25519_unpackneg_vartime(&get1, pk)) return -1; get_hram(hram,sm,pk,m,smlen); sc25519_from64bytes(&schram, hram); sc25519_from32bytes(&scs, sm+32); ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs); ge25519_pack(t2, &get2); ret = crypto_verify_32(sm, t2); if (!ret) { for(i=0;i<smlen-64;i++) m[i] = sm[i + 64]; *mlen = smlen-64; } else { for(i=0;i<smlen-64;i++) m[i] = 0; } return ret; }
// Step 3 bis // verify pk_r = y.B - c.pk with pk = sk.B int schnorr_id_verify(const uint8_t pk[SCHNORR_PUBLICKEYBYTES], const uint8_t pk_r[SCHNORR_PUBLICKEYBYTES], const uint8_t challenge[SCHNORR_ID_CHALLENGEBYTES], const uint8_t response[SCHNORR_ID_RESPONSEBYTES]) { ge25519 ge_pk_neg; sc25519 sc_challenge; sc25519 sc_response; ge25519 ge_pk_r_verifier; uint8_t pk_r_verifier[SCHNORR_PUBLICKEYBYTES]; if (ge25519_unpackneg_vartime(&ge_pk_neg, pk)) return -1; sc25519_from_challenge_bytes(&sc_challenge, challenge); sc25519_from32bytes(&sc_response, response); ge25519_double_scalarmult_vartime(&ge_pk_r_verifier, &ge_pk_neg, &sc_challenge, &ge25519_base, &sc_response); ge25519_pack(pk_r_verifier, &ge_pk_r_verifier); return verify_32(pk_r, pk_r_verifier); }
/* Do the scalar multiplication of <b>pubkey</b> with the group order * <b>modm_m</b>. Place the result in <b>out</b> which must be at least 32 * bytes long. */ int ed25519_donna_scalarmult_with_group_order(unsigned char *out, const unsigned char *pubkey) { static const bignum256modm ALIGN(16) zero = { 0 }; unsigned char pkcopy[32]; ge25519 ALIGN(16) Point, Result; /* No "ge25519_unpack", negate the public key and unpack it back. * See ed25519_donna_blind_public_key() */ memcpy(pkcopy, pubkey, 32); pkcopy[31] ^= (1<<7); if (!ge25519_unpack_negative_vartime(&Point, pkcopy)) { return -1; /* error: bail out */ } /* There is no regular scalarmult function so we have to do: * Result = l*P + 0*B */ ge25519_double_scalarmult_vartime(&Result, &Point, modm_m, zero); ge25519_pack(out, &Result); return 0; }
int ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) { ge25519 MM16 R, A; hash_512bits hash; bignum256modm hram, S; unsigned char checkR[32]; if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) return -1; /* hram = H(R,A,m) */ ed25519_hram(hash, RS, pk, m, mlen); expand256_modm(hram, hash, 64); /* S */ expand256_modm(S, RS + 32, 32); /* SB - H(R,A,m)A */ ge25519_double_scalarmult_vartime(&R, &A, hram, S); ge25519_pack(checkR, &R); /* check that R = SB - H(R,A,m)A */ return ed25519_verify(RS, checkR, 32) ? 0 : -1; }