diff --git a/LICENSE b/LICENSE index 10f0ec1..22a10c8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,5 @@ 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 modification, are permitted provided that the following conditions are met: diff --git a/internal/radix51/fe.go b/internal/radix51/fe.go index bf9ccd0..0756e87 100644 --- a/internal/radix51/fe.go +++ b/internal/radix51/fe.go @@ -1,4 +1,5 @@ // 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 // license that can be found in the LICENSE file. @@ -7,6 +8,7 @@ package radix51 import ( + "crypto/subtle" "math/big" "math/bits" ) @@ -330,3 +332,49 @@ func FeToBig(h *FieldElement) *big.Int { out := new(big.Int) 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)) +}