mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-23 16:08:17 +00:00
Merge pull request #81 from jhoenicke/master
Move public key recovery (verify) to trezor-crypto
This commit is contained in:
commit
d41e46f842
@ -122,28 +122,9 @@ int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message
|
|||||||
|
|
||||||
int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature)
|
int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature)
|
||||||
{
|
{
|
||||||
bignum256 r, s, e;
|
|
||||||
curve_point cp, cp2;
|
|
||||||
SHA256_CTX ctx;
|
SHA256_CTX ctx;
|
||||||
uint8_t pubkey[65], addr_raw[21], hash[32];
|
uint8_t pubkey[65], addr_raw[21], hash[32];
|
||||||
|
|
||||||
uint8_t nV = signature[0];
|
|
||||||
if (nV < 27 || nV >= 35) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bool compressed;
|
|
||||||
compressed = (nV >= 31);
|
|
||||||
if (compressed) {
|
|
||||||
nV -= 4;
|
|
||||||
}
|
|
||||||
uint8_t recid = nV - 27;
|
|
||||||
// read r and s
|
|
||||||
bn_read_be(signature + 1, &r);
|
|
||||||
bn_read_be(signature + 33, &s);
|
|
||||||
// x = r
|
|
||||||
memcpy(&cp.x, &r, sizeof(bignum256));
|
|
||||||
// compute y from x
|
|
||||||
uncompress_coords(&secp256k1, recid % 2, &cp.x, &cp.y);
|
|
||||||
// calculate hash
|
// calculate hash
|
||||||
sha256_Init(&ctx);
|
sha256_Init(&ctx);
|
||||||
sha256_Update(&ctx, (const uint8_t *)"\x18" "Bitcoin Signed Message:" "\n", 25);
|
sha256_Update(&ctx, (const uint8_t *)"\x18" "Bitcoin Signed Message:" "\n", 25);
|
||||||
@ -153,30 +134,27 @@ int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_
|
|||||||
sha256_Update(&ctx, message, message_len);
|
sha256_Update(&ctx, message, message_len);
|
||||||
sha256_Final(&ctx, hash);
|
sha256_Final(&ctx, hash);
|
||||||
sha256_Raw(hash, 32, hash);
|
sha256_Raw(hash, 32, hash);
|
||||||
// e = -hash
|
|
||||||
bn_read_be(hash, &e);
|
uint8_t recid = signature[0] - 27;
|
||||||
bn_subtract(&secp256k1.order, &e, &e);
|
if (recid >= 8) {
|
||||||
// r = r^-1
|
return 1;
|
||||||
bn_inverse(&r, &secp256k1.order);
|
|
||||||
point_multiply(&secp256k1, &s, &cp, &cp);
|
|
||||||
scalar_multiply(&secp256k1, &e, &cp2);
|
|
||||||
point_add(&secp256k1, &cp2, &cp);
|
|
||||||
point_multiply(&secp256k1, &r, &cp, &cp);
|
|
||||||
pubkey[0] = 0x04;
|
|
||||||
bn_write_be(&cp.x, pubkey + 1);
|
|
||||||
bn_write_be(&cp.y, pubkey + 33);
|
|
||||||
// check if the address is correct
|
|
||||||
if (compressed) {
|
|
||||||
pubkey[0] = 0x02 | (cp.y.val[0] & 0x01);
|
|
||||||
}
|
}
|
||||||
|
bool compressed = (recid >= 4);
|
||||||
|
recid &= 3;
|
||||||
|
|
||||||
|
// check if signature verifies the digest and recover the public key
|
||||||
|
if (ecdsa_verify_digest_recover(&secp256k1, pubkey, signature + 1, hash, recid) != 0) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
// convert public key to compressed pubkey if necessary
|
||||||
|
if (compressed) {
|
||||||
|
pubkey[0] = 0x02 | (pubkey[64] & 1);
|
||||||
|
}
|
||||||
|
// check if the address is correct
|
||||||
ecdsa_get_address_raw(pubkey, address_raw[0], addr_raw);
|
ecdsa_get_address_raw(pubkey, address_raw[0], addr_raw);
|
||||||
if (memcmp(addr_raw, address_raw, 21) != 0) {
|
if (memcmp(addr_raw, address_raw, 21) != 0) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
// check if signature verifies the digest
|
|
||||||
if (ecdsa_verify_digest(&secp256k1, pubkey, signature + 1, hash) != 0) {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user