secp256k1: Expose IsOddBit on field val type.
This exposes a new function on the FieldVal type named IsOddBit which operates similarly to IsOdd except it returns a 0 or 1. This is being provided because it is not possible in Go to convert from a bool to numeric value in constant time and many constant-time operations require a numeric value. Since the type is now exported for external use, consumers would otherwise have no way to perform the conversion.
This commit is contained in:
parent
be680db523
commit
05cc323f2a
@ -500,6 +500,21 @@ func (f *FieldVal) IsOne() bool {
|
||||
return bits == 0
|
||||
}
|
||||
|
||||
// IsOddBit returns 1 when the field value is an odd number or 0 otherwise in
|
||||
// constant time.
|
||||
//
|
||||
// Note that a bool is not used here because it is not possible in Go to convert
|
||||
// from a bool to numeric value in constant time and many constant-time
|
||||
// operations require a numeric value. See IsOdd for the version that returns a
|
||||
// bool.
|
||||
//
|
||||
// Preconditions:
|
||||
// - The field value MUST be normalized
|
||||
func (f *FieldVal) IsOddBit() uint32 {
|
||||
// Only odd numbers have the bottom bit set.
|
||||
return f.n[0] & 1
|
||||
}
|
||||
|
||||
// IsOdd returns whether or not the field value is an odd number in constant
|
||||
// time.
|
||||
//
|
||||
|
||||
@ -490,8 +490,8 @@ func TestFieldNormalize(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestFieldIsOdd ensures that checking if a field value IsOdd works as
|
||||
// expected.
|
||||
// TestFieldIsOdd ensures that checking if a field value is odd via IsOdd and
|
||||
// IsOddBit works as expected.
|
||||
func TestFieldIsOdd(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string // test description
|
||||
@ -528,12 +528,20 @@ func TestFieldIsOdd(t *testing.T) {
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
result := new(FieldVal).SetHex(test.in).IsOdd()
|
||||
f := new(FieldVal).SetHex(test.in)
|
||||
result := f.IsOdd()
|
||||
if result != test.expected {
|
||||
t.Errorf("%s: wrong result -- got: %v, want: %v", test.name,
|
||||
result, test.expected)
|
||||
continue
|
||||
}
|
||||
|
||||
result2 := f.IsOddBit() == 1
|
||||
if result2 != test.expected {
|
||||
t.Errorf("%s: wrong result -- got: %v, want: %v", test.name,
|
||||
result2, test.expected)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -881,7 +881,7 @@ func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, byte) {
|
||||
// points since that would require breaking the ECDLP, but, in practice
|
||||
// this strongly implies with extremely high probability that there are
|
||||
// only a few actual points for which this case is true.
|
||||
pubKeyRecoveryCode := byte(overflow<<1) | byte(kG.y.n[0]&0x01)
|
||||
pubKeyRecoveryCode := byte(overflow<<1) | byte(kG.y.IsOddBit())
|
||||
|
||||
// Step 4.
|
||||
//
|
||||
|
||||
Loading…
Reference in New Issue
Block a user