11//! secp256k1 signature types and helper functions.
22
3- use crate :: { ToBigEndian , Word } ;
4- use ethers_core:: types:: Bytes ;
3+ use crate :: { ToBigEndian , ToWord , Word } ;
4+ use ethers_core:: {
5+ types:: { Address , Bytes } ,
6+ utils:: keccak256,
7+ } ;
58use halo2_proofs:: {
69 arithmetic:: { CurveAffine , FieldExt } ,
710 halo2curves:: {
@@ -23,32 +26,33 @@ pub fn sign(
2326 randomness : secp256k1:: Fq ,
2427 sk : secp256k1:: Fq ,
2528 msg_hash : secp256k1:: Fq ,
26- ) -> ( secp256k1:: Fq , secp256k1:: Fq ) {
29+ ) -> ( secp256k1:: Fq , secp256k1:: Fq , u8 ) {
2730 let randomness_inv =
2831 Option :: < secp256k1:: Fq > :: from ( randomness. invert ( ) ) . expect ( "cannot invert randomness" ) ;
2932 let generator = Secp256k1Affine :: generator ( ) ;
3033 let sig_point = generator * randomness;
34+ let sig_v: bool = sig_point. to_affine ( ) . y . is_odd ( ) . into ( ) ;
35+
3136 let x = * Option :: < Coordinates < _ > > :: from ( sig_point. to_affine ( ) . coordinates ( ) )
3237 . expect ( "point is the identity" )
3338 . x ( ) ;
3439
35- let x_repr = & mut vec ! [ 0u8 ; 32 ] ;
36- x_repr. copy_from_slice ( x. to_bytes ( ) . as_slice ( ) ) ;
37-
3840 let mut x_bytes = [ 0u8 ; 64 ] ;
39- x_bytes[ ..32 ] . copy_from_slice ( & x_repr [ .. ] ) ;
41+ x_bytes[ ..32 ] . copy_from_slice ( & x . to_bytes ( ) ) ;
4042
4143 let sig_r = secp256k1:: Fq :: from_bytes_wide ( & x_bytes) ; // get x cordinate (E::Base) on E::Scalar
44+
4245 let sig_s = randomness_inv * ( msg_hash + sig_r * sk) ;
43- ( sig_r, sig_s)
46+ ( sig_r, sig_s, u8 :: from ( sig_v ) )
4447}
4548
4649/// Signature data required by the SignVerify Chip as input to verify a
4750/// signature.
4851#[ derive( Clone , Debug ) ]
4952pub struct SignData {
50- /// Secp256k1 signature point
51- pub signature : ( secp256k1:: Fq , secp256k1:: Fq ) ,
53+ /// Secp256k1 signature point (r, s, v)
54+ /// v must be 0 or 1
55+ pub signature : ( secp256k1:: Fq , secp256k1:: Fq , u8 ) ,
5256 /// Secp256k1 public key
5357 pub pk : Secp256k1Affine ,
5458 /// Message being hashed before signing.
@@ -57,7 +61,20 @@ pub struct SignData {
5761 pub msg_hash : secp256k1:: Fq ,
5862}
5963
64+ impl SignData {
65+ /// Recover address of the signature
66+ pub fn get_addr ( & self ) -> Word {
67+ let pk_le = pk_bytes_le ( & self . pk ) ;
68+ let pk_be = pk_bytes_swap_endianness ( & pk_le) ;
69+ let pk_hash = keccak256 ( pk_be) ;
70+ let mut addr_bytes = [ 0u8 ; 20 ] ;
71+ addr_bytes. copy_from_slice ( & pk_hash[ 12 ..] ) ;
72+ Address :: from ( addr_bytes) . to_word ( )
73+ }
74+ }
75+
6076lazy_static ! {
77+ // FIXME: use Transaction::dummy().sign_data() instead when we merged the develop branch
6178 static ref SIGN_DATA_DEFAULT : SignData = {
6279 let generator = Secp256k1Affine :: generator( ) ;
6380 let sk = secp256k1:: Fq :: one( ) ;
@@ -80,10 +97,10 @@ lazy_static! {
8097 . expect( "hash length isn't 32 bytes" ) ;
8198 let msg_hash = secp256k1:: Fq :: from_bytes( & msg_hash) . unwrap( ) ;
8299 let randomness = secp256k1:: Fq :: one( ) ;
83- let ( sig_r, sig_s) = sign( randomness, sk, msg_hash) ;
100+ let ( sig_r, sig_s, v ) = sign( randomness, sk, msg_hash) ;
84101
85102 SignData {
86- signature: ( sig_r, sig_s) ,
103+ signature: ( sig_r, sig_s, v ) ,
87104 pk,
88105 msg: msg. into( ) ,
89106 msg_hash,
@@ -92,12 +109,12 @@ lazy_static! {
92109}
93110
94111impl Default for SignData {
112+ // Hardcoded valid signature corresponding to a hardcoded private key and
113+ // message hash generated from "nothing up my sleeve" values to make the
114+ // ECDSA chip pass the constraints, to be use for padding signature
115+ // verifications (where the constraints pass, but we don't care about the
116+ // message hash and public key).
95117 fn default ( ) -> Self {
96- // Hardcoded valid signature corresponding to a hardcoded private key and
97- // message hash generated from "nothing up my sleeve" values to make the
98- // ECDSA chip pass the constraints, to be use for padding signature
99- // verifications (where the constraints pass, but we don't care about the
100- // message hash and public key).
101118 SIGN_DATA_DEFAULT . clone ( )
102119 }
103120}
0 commit comments