mirror of https://github.com/gtank/ristretto255
internal/radix51: add constant time field operations
This commit is contained in:
parent
7ec609da40
commit
fe6e0954e0
1
LICENSE
1
LICENSE
|
@ -1,4 +1,5 @@
|
||||||
Copyright 2017 George Tankersley. All rights reserved.
|
Copyright 2017 George Tankersley. All rights reserved.
|
||||||
|
Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright (c) 2017 George Tankersley. All rights reserved.
|
// Copyright (c) 2017 George Tankersley. All rights reserved.
|
||||||
|
// Copyright (c) 2019 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,6 +8,7 @@
|
||||||
package radix51
|
package radix51
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/subtle"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
)
|
)
|
||||||
|
@ -330,3 +332,49 @@ func FeToBig(h *FieldElement) *big.Int {
|
||||||
out := new(big.Int)
|
out := new(big.Int)
|
||||||
return out.SetBits(words)
|
return out.SetBits(words)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FeEqual returns 1 if a and b are equal, and 0 otherwise.
|
||||||
|
func FeEqual(a, b *FieldElement) int {
|
||||||
|
var sa, sb [32]byte
|
||||||
|
FeToBytes(&sa, a)
|
||||||
|
FeToBytes(&sb, b)
|
||||||
|
return subtle.ConstantTimeCompare(sa[:], sb[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// FeSelect sets out to v if cond == 1, and to u if cond == 0.
|
||||||
|
// out, v and u are allowed to overlap.
|
||||||
|
func FeSelect(out, v, u *FieldElement, cond int) {
|
||||||
|
b := uint64(cond) * 0xffffffffffffffff
|
||||||
|
out[0] = (b & v[0]) | (^b & u[0])
|
||||||
|
out[1] = (b & v[1]) | (^b & u[1])
|
||||||
|
out[2] = (b & v[2]) | (^b & u[2])
|
||||||
|
out[3] = (b & v[3]) | (^b & u[3])
|
||||||
|
out[4] = (b & v[4]) | (^b & u[4])
|
||||||
|
}
|
||||||
|
|
||||||
|
// FeCondNeg sets u to -u if cond == 1, and to u if cond == 0.
|
||||||
|
func FeCondNeg(u *FieldElement, cond int) {
|
||||||
|
var neg FieldElement
|
||||||
|
FeNeg(&neg, u)
|
||||||
|
|
||||||
|
b := uint64(cond) * 0xffffffffffffffff
|
||||||
|
u[0] ^= b & (u[0] ^ neg[0])
|
||||||
|
u[1] ^= b & (u[1] ^ neg[1])
|
||||||
|
u[2] ^= b & (u[2] ^ neg[2])
|
||||||
|
u[3] ^= b & (u[3] ^ neg[3])
|
||||||
|
u[4] ^= b & (u[4] ^ neg[4])
|
||||||
|
}
|
||||||
|
|
||||||
|
// FeIsNegative returns 1 if u is negative, and 0 otherwise.
|
||||||
|
func FeIsNegative(u *FieldElement) int {
|
||||||
|
var b [32]byte
|
||||||
|
FeToBytes(&b, u)
|
||||||
|
return int(b[0] & 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FeAbs sets out to |u|. out and u are allowed to overlap.
|
||||||
|
func FeAbs(out, u *FieldElement) {
|
||||||
|
var neg FieldElement
|
||||||
|
FeNeg(&neg, u)
|
||||||
|
FeSelect(out, &neg, u, FeIsNegative(u))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue