status-go/vendor/github.com/kilic/bls12-381/wnaf.go

36 lines
662 B
Go
Raw Normal View History

Feature/key compression (#1990) ## What has changed? I've introduced to the public binding functionality that will compress and decompress public keys of a variety of encoding and key types. This functionality supports all major byte encoding formats and the following EC public key types: - `secp256k1` pks - `bls12-381 g1` pks - `bls12-381 g2` pks ## Why make the change? We want shorter public (chat) keys and we want to be future proof and encoding agnostic. See the issue here https://github.com/status-im/status-go/issues/1937 --- * Added basic signature for compresspk and uncompresspk * Added basic encoding information * make vendor * formatted imports for the linter * Reformatted imports hoping linter likes it * This linter is capricious * Added check that the secp256k1 key is valid * Added test for valid key * Added multiformat/go-varint dep * Added public key type handling * Added key decompression with key type handling * Added handling for '0x' type indentifying * Added more robust testing * Less lint for the linting gods * make vendor for bls12_381 * Added bls12-381 compression tests * Added decompress key expected results * Refactor of typed and untyped keys in tests * Lint god appeasment * Refactor of sample public keys * Implemented bls12-381 decompression * gofmt * Renamed decode/encode funcs to be more descriptive * Added binary bindings for key de/compression * Refactor of func parameters gomobile is a bit tempermental using raw bytes as a parameter, so I've decided to use string only inputs and outputs * gofmt * Added function documentation * Moved multiformat de/compression into api/multiformat ns * Moved multiformat de/compression into api/multiformat ns * Changed compress to serialize on API
2020-06-23 10:47:17 +00:00
package bls12381
import (
"math/big"
)
func wnaf(e0 *big.Int, window uint) []int64 {
e := new(big.Int).Set(e0)
zero := big.NewInt(0)
if e.Cmp(zero) == 0 {
return []int64{}
}
max := int64(1 << window)
midpoint := int64(1 << (window - 1))
modulusMask := uint64(1<<window) - 1
var out []int64
for e.Cmp(zero) != 0 {
var z int64
if e.Bit(0)&1 == 1 {
maskedBits := int64(e.Uint64() & modulusMask)
if maskedBits > midpoint {
z = maskedBits - max
e.Add(e, new(big.Int).SetInt64(0-z))
} else {
z = maskedBits
e.Sub(e, new(big.Int).SetInt64(z))
}
} else {
z = 0
}
out = append(out, z)
e.Rsh(e, 1)
}
return out
}