func readBigInt(r io.Reader, b []byte, sign byte) (interface{}, error) { if _, err := io.ReadFull(r, b); err != nil { return nil, err } size := len(b) hsize := size >> 1 for i := 0; i < hsize; i++ { b[i], b[size-i-1] = b[size-i-1], b[i] } v := new(big.Int).SetBytes(b) if sign != 0 { v = v.Neg(v) } // try int and int64 v64 := v.Int64() if x := int(v64); v.Cmp(big.NewInt(int64(x))) == 0 { return x, nil } else if v.Cmp(big.NewInt(v64)) == 0 { return v64, nil } return v, nil }
func roundHalf(f func(c int, odd uint) (roundUp bool)) func(z, q *Dec, rA, rB *big.Int) *Dec { return func(z, q *Dec, rA, rB *big.Int) *Dec { z.Set(q) brA, brB := rA.BitLen(), rB.BitLen() if brA < brB-1 { // brA < brB-1 => |rA| < |rB/2| return z } roundUp := false srA, srB := rA.Sign(), rB.Sign() s := srA * srB if brA == brB-1 { rA2 := new(big.Int).Lsh(rA, 1) if s < 0 { rA2.Neg(rA2) } roundUp = f(rA2.Cmp(rB)*srB, z.UnscaledBig().Bit(0)) } else { // brA > brB-1 => |rA| > |rB/2| roundUp = true } if roundUp { z.UnscaledBig().Add(z.UnscaledBig(), intSign[s+1]) } return z } }
// ToBase produces n in base b. For example // // ToBase(2047, 22) -> [1, 5, 4] // // 1 * 22^0 1 // 5 * 22^1 110 // 4 * 22^2 1936 // ---- // 2047 // // ToBase panics for bases < 2. func ToBase(n *big.Int, b int) []int { var nn big.Int nn.Set(n) if b < 2 { panic("invalid base") } k := 1 switch nn.Sign() { case -1: nn.Neg(&nn) k = -1 case 0: return []int{0} } bb := big.NewInt(int64(b)) var r []int rem := big.NewInt(0) for nn.Sign() != 0 { nn.QuoRem(&nn, bb, rem) r = append(r, k*int(rem.Int64())) } return r }
func (v *Value) String() string { if v.IsZero() { return "0" } if v.Native && v.IsScientific() { value := strconv.FormatUint(v.Num, 10) offset := strconv.FormatInt(v.Offset, 10) if v.Negative { return "-" + value + "e" + offset } return value + "e" + offset } value := big.NewInt(int64(v.Num)) if v.Negative { value.Neg(value) } var offset *big.Int if v.Native { offset = big.NewInt(-6) } else { offset = big.NewInt(v.Offset) } exp := offset.Exp(bigTen, offset.Neg(offset), nil) rat := big.NewRat(0, 1).SetFrac(value, exp) left := rat.FloatString(0) if rat.IsInt() { return left } length := len(left) if v.Negative { length -= 1 } return strings.TrimRight(rat.FloatString(32-length), "0") }
// TestPoint verifies that a point (x1,y2) does not equal another point (x1,y2) or it's reflection on 0 func (curve Curve) TestPoint(x1, y1, x2, y2 *big.Int) (bool, error) { _, err := curve.TestCoordinate(x1) if err != nil { return false, err } _, err = curve.TestCoordinate(x2) if err != nil { return false, err } if x1.Cmp(x1) == 0 && y1.Cmp(y2) == 0 { // Same return false, ErrCoordinateBase } if x1.Cmp(y1) == 0 && y1.Cmp(x2) == 0 { // Reflect return false, ErrCoordinateBase } x2neg := new(big.Int) x2neg = x2neg.Neg(x2) y2neg := new(big.Int) y2neg = y2neg.Neg(y2) if x1.Cmp(x2neg) == 0 { return false, ErrCoordinateBase } if x1.Cmp(y2neg) == 0 && y1.Cmp(x2neg) == 0 { return false, ErrCoordinateBase } return true, nil }
// CompactToBig converts a compact representation of a whole number N to an // unsigned 32-bit number. The representation is similar to IEEE754 floating // point numbers. // // Like IEEE754 floating point, there are three basic components: the sign, // the exponent, and the mantissa. They are broken out as follows: // // * the most significant 8 bits represent the unsigned base 256 exponent // * bit 23 (the 24th bit) represents the sign bit // * the least significant 23 bits represent the mantissa // // ------------------------------------------------- // | Exponent | Sign | Mantissa | // ------------------------------------------------- // | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | // ------------------------------------------------- // // The formula to calculate N is: // N = (-1^sign) * mantissa * 256^(exponent-3) // // This compact form is only used in bitcoin to encode unsigned 256-bit numbers // which represent difficulty targets, thus there really is not a need for a // sign bit, but it is implemented here to stay consistent with bitcoind. func CompactToBig(compact uint32) *big.Int { // Extract the mantissa, sign bit, and exponent. mantissa := compact & 0x007fffff isNegative := compact&0x00800000 != 0 exponent := uint(compact >> 24) // Since the base for the exponent is 256, the exponent can be treated // as the number of bytes to represent the full 256-bit number. So, // treat the exponent as the number of bytes and shift the mantissa // right or left accordingly. This is equivalent to: // N = mantissa * 256^(exponent-3) var bn *big.Int if exponent <= 3 { mantissa >>= 8 * (3 - exponent) bn = big.NewInt(int64(mantissa)) } else { bn = big.NewInt(int64(mantissa)) bn.Lsh(bn, 8*(exponent-3)) } // Make it negative if the sign bit is set. if isNegative { bn = bn.Neg(bn) } return bn }
func (i BigInt) floatString(verb byte, prec int) string { switch verb { case 'f', 'F': str := fmt.Sprintf("%d", i.Int) if prec > 0 { str += "." + zeros(prec) } return str case 'e', 'E': // The exponent will alway be >= 0. sign := "" var x big.Int x.Set(i.Int) if x.Sign() < 0 { sign = "-" x.Neg(&x) } return eFormat(verb, prec, sign, x.String(), eExponent(&x)) case 'g', 'G': // Exponent is always positive so it's easy. var x big.Int x.Set(i.Int) if eExponent(&x) >= prec { // Use e format. verb -= 2 // g becomes e. return trimEZeros(verb, i.floatString(verb, prec-1)) } // Use f format, but this is just an integer. return fmt.Sprintf("%d", i.Int) default: Errorf("can't handle verb %c for big int", verb) } return "" }
// Neg() returns a polynomial Q = -P func (p *Poly) Neg() Poly { var q Poly = make([]*big.Int, len(*p)) for i := 0; i < len(*p); i++ { b := new(big.Int) b.Neg((*p)[i]) q[i] = b } return q }
func unaryIntOp(x *big.Int, op token.Token) interface{} { var z big.Int switch op { case token.ADD: return z.Set(x) case token.SUB: return z.Neg(x) case token.XOR: return z.Not(x) } panic("unreachable") }
func (d Decimal) Bytes() []byte { bytes := make([]byte, 16) binary.BigEndian.PutUint32(bytes[0:4], d.integer[3]) binary.BigEndian.PutUint32(bytes[4:8], d.integer[2]) binary.BigEndian.PutUint32(bytes[8:12], d.integer[1]) binary.BigEndian.PutUint32(bytes[12:16], d.integer[0]) var x big.Int x.SetBytes(bytes) if !d.positive { x.Neg(&x) } return scaleBytes(x.String(), d.scale) }
// trunc truncates a value to the range of the given type. func (t *_type) trunc(x *big.Int) *big.Int { r := new(big.Int) m := new(big.Int) m.Lsh(one, t.bits) m.Sub(m, one) r.And(x, m) if t.signed && r.Bit(int(t.bits)-1) == 1 { m.Neg(one) m.Lsh(m, t.bits) r.Or(r, m) } return r }
// eExponent returns the exponent to use to display i in 1.23e+04 format. func eExponent(x *big.Int) int { if x.Sign() < 0 { x.Neg(x) } e := 0 for x.Cmp(bigIntBillion) >= 0 { e += 9 x.Quo(x, bigIntBillion) } for x.Cmp(bigIntTen) >= 0 { e++ x.Quo(x, bigIntTen) } return e }
func testNegativeInputs(t *testing.T, curve elliptic.Curve, tag string) { key, err := GenerateKey(curve, rand.Reader) if err != nil { t.Errorf("failed to generate key for %q", tag) } var hash [32]byte r := new(big.Int).SetInt64(1) r.Lsh(r, 550 /* larger than any supported curve */) r.Neg(r) if Verify(&key.PublicKey, hash[:], r, r) { t.Errorf("bogus signature accepted for %q", tag) } }
func instantiateINTEGER(inst *Instance, data interface{}, p *pathNode) (*Instance, error) { switch data := data.(type) { case *UnmarshalledPrimitive: if len(data.Data) == 0 { return nil, fmt.Errorf("%vAttempt to instantiate INTEGER from empty DER data", p) } var b big.Int b.SetBytes(data.Data) if data.Data[0]&128 != 0 { // negative number var x big.Int x.SetBit(&x, len(data.Data)*8, 1) x.Sub(&x, &b) b.Neg(&x) } return instantiateINTEGER(inst, &b, p) case *Instance: inst.value = data.value case *big.Int: i := int(data.Int64()) if big.NewInt(int64(i)).Cmp(data) == 0 { inst.value = i // store as int if possible } else { inst.value = data // use *big.Int if necessary } case int: inst.value = data case float64: if math.Floor(data) != data { return nil, fmt.Errorf("%vAttempt to instantiate INTEGER with non-integral float64: %v", p, data) } inst.value = int(data) case string: if i, found := inst.namedints[data]; found { inst.value = i } else { bi := new(big.Int) _, ok := bi.SetString(data, 10) if ok { return instantiateINTEGER(inst, bi, p) } else { return nil, fmt.Errorf("%vAttempt to instantiate INTEGER/ENUMERATED from illegal string: %v", p, data) } } default: return nil, instantiateTypeError(p, "INTEGER", data) } return inst, nil }
// parseBigInt treats the given bytes as a big-endian, signed integer and returns // the result. func parseBigInt(bytes []byte) *big.Int { ret := new(big.Int) if len(bytes) > 0 && bytes[0]&0x80 == 0x80 { // This is a negative number. notBytes := make([]byte, len(bytes)) for i := range notBytes { notBytes[i] = ^bytes[i] } ret.SetBytes(notBytes) ret.Add(ret, bigOne) ret.Neg(ret) return ret } ret.SetBytes(bytes) return ret }
func IsValidBox(c elliptic.Curve, box *Checkbox, px *big.Int, py *big.Int) bool { if !c.IsOnCurve(box.ax, box.ay) || !c.IsOnCurve(box.bx, box.by) { return false } //Explanation of how this works //(c1,r1) validates equality of log g A and log p B-g //(c2, r2) validates euqality of log g A and log p B //each of these proofs is just a Schnorr proof of knowledge of //the log, which work for both simultaneously //We require c1+c2=H(A, B t1,t2,t3,t4) which enforces that only one //of these can be faked, hence giving an or proof v1x, v1y := doublescalarmult(c, c.Params().Gx, c.Params().Gy, box.r1.Bytes(), box.ax, box.ay, box.c1.Bytes()) t4x := c.Params().Gx t4y := new(big.Int) t4y.Neg(c.Params().Gy) t4y.Mod(t4y, c.Params().P) bgx, bgy := c.Add(box.bx, box.by, t4x, t4y) v2x, v2y := doublescalarmult(c, px, py, box.r1.Bytes(), bgx, bgy, box.c1.Bytes()) v3x, v3y := doublescalarmult(c, c.Params().Gx, c.Params().Gy, box.r2.Bytes(), box.ax, box.ay, box.c2.Bytes()) v4x, v4y := doublescalarmult(c, px, py, box.r2.Bytes(), box.bx, box.by, box.c2.Bytes()) var entries [6][]byte entries[0] = elliptic.Marshal(c, box.ax, box.ay) entries[1] = elliptic.Marshal(c, box.bx, box.by) entries[2] = elliptic.Marshal(c, v1x, v1y) entries[3] = elliptic.Marshal(c, v2x, v2y) entries[4] = elliptic.Marshal(c, v3x, v3y) entries[5] = elliptic.Marshal(c, v4x, v4y) challenge := sha256.Sum256(bytes.Join(entries[:], []byte{})) ctot := big.NewInt(0) ctot.SetBytes(challenge[:]) ctot.Mod(ctot, c.Params().N) t := big.NewInt(0) t.Add(box.c1, box.c2) t.Mod(t, c.Params().N) if t.Cmp(ctot) != 0 { return false } return true }
// parseBigInt treats the given bytes as a big-endian, signed integer and returns // the result. func parseBigInt(bytes []byte) (*big.Int, error) { if err := checkInteger(bytes); err != nil { return nil, err } ret := new(big.Int) if len(bytes) > 0 && bytes[0]&0x80 == 0x80 { // This is a negative number. notBytes := make([]byte, len(bytes)) for i := range notBytes { notBytes[i] = ^bytes[i] } ret.SetBytes(notBytes) ret.Add(ret, bigOne) ret.Neg(ret) return ret, nil } ret.SetBytes(bytes) return ret, nil }
func RecoverPubKeyFromSignature(r, s *big.Int, msg []byte, curve *bitelliptic.BitCurve, recid uint) (qx, qy *big.Int, err error) { if recid > 3 { return nil, nil, fmt.Errorf("Illegal recid %v - must be in 0..3", recid) } order := curve.N i := recid / 2 field := curve.P x := new(big.Int).Set(order) x.Mul(x, big.NewInt(int64(i))) x.Add(x, r) if x.Cmp(field) >= 0 { err = fmt.Errorf("%v >= %v", x, field) return } rx, ry, err := uncompressPoint(x, curve, 0 == (recid%2)) if err != nil { return nil, nil, err } if !curve.IsOnCurve(rx, ry) { return nil, nil, fmt.Errorf("Point %d, %d not on curve", rx, ry) } e := new(big.Int).SetBytes(msg) if 8*len(msg) > curve.BitSize { e.Rsh(e, uint(8-(curve.BitSize&7))) } e.Neg(e).Mod(e, order) var rr, sor, eor big.Int rr.ModInverse(r, order) //return nil, nil, fmt.Errorf("r: %d, r_inv: %d", r, &rr) //Q = (R.multiply(s).add(G.multiply(minus_e))).multiply(inv_r); sor.Mul(s, &rr) eor.Mul(e, &rr) Georx, Geory := curve.ScalarBaseMult(eor.Bytes()) Rsorx, Rsory := curve.ScalarMult(rx, ry, sor.Bytes()) qx, qy = curve.Add(Georx, Geory, Rsorx, Rsory) return }
func join(shares []Share) *big.Int { zero := big.NewInt(0) accum := big.NewInt(1) for formula := 0; formula < len(shares); formula++ { numerator := big.NewInt(1) denominator := big.NewInt(1) value := new(big.Int) value.Set(shares[formula].Part) for count := 0; count < len(shares); count++ { if formula == count { continue } startposition := big.NewInt(shares[formula].ID) nextposition := big.NewInt(shares[count].ID) negnextpos := new(big.Int) negnextpos.Neg(nextposition) numerator.Mul(numerator, negnextpos) denominator.Mul(denominator, startposition.Sub(startposition, nextposition)) } value.Mul(value, numerator).Mul(value, big.NewInt(2)) if denominator.Cmp(zero) < 0 { value.Add(value, big.NewInt(2)) } else { value.Add(value, big.NewInt(1)) } denominator.Mul(denominator, big.NewInt(2)) value.Div(value, denominator) accum.Add(accum, value) } return accum }
// asInt converts a byte array to a bignum by treating it as a little endian // number with sign bit. func asInt(v []byte) (*big.Int, error) { // Only 32bit numbers allowed. if len(v) > 4 { return nil, ErrStackNumberTooBig } if len(v) == 0 { return big.NewInt(0), nil } negative := false origlen := len(v) msb := v[len(v)-1] if msb&0x80 == 0x80 { negative = true // remove sign bit msb &= 0x7f } // trim leading 0 bytes for ; msb == 0; msb = v[len(v)-1] { v = v[:len(v)-1] if len(v) == 0 { break } } // reverse bytes with a copy since stack is immutable. intArray := make([]byte, len(v)) for i := range v { intArray[len(v)-i-1] = v[i] } // IFF the value is negative and no 0 bytes were trimmed, // the leading byte needs to be sign corrected if negative && len(intArray) == origlen { intArray[0] &= 0x7f } num := new(big.Int).SetBytes(intArray) if negative { num = num.Neg(num) } return num, nil }
/* Thanks to jackjack for providing me with this nice solution: https://bitcointalk.org/index.php?topic=162805.msg2112936#msg2112936 */ func (sig *Signature) RecoverPublicKey(msg []byte, recid int) (key *PublicKey) { x := new(big.Int).Set(secp256k1.N) x.Mul(x, big.NewInt(int64(recid/2))) x.Add(x, sig.R) y := DecompressPoint(x, (recid&1) != 0) e := new(big.Int).SetBytes(msg) new(big.Int).DivMod(e.Neg(e), secp256k1.N, e) _x, _y := secp256k1.ScalarMult(x, y, sig.S.Bytes()) x, y = secp256k1.ScalarMult(secp256k1.Gx, secp256k1.Gy, e.Bytes()) _x, _y = secp256k1.Add(_x, _y, x, y) x, y = secp256k1.ScalarMult(_x, _y, new(big.Int).ModInverse(sig.R, secp256k1.N).Bytes()) key = new(PublicKey) key.Curve = secp256k1 key.X = x key.Y = y return }
// number = int_lit [ "p" int_lit ] . // func (p *gcParser) parseNumber() (x operand) { x.mode = constant // mantissa neg, val := p.parseInt() mant, ok := new(big.Int).SetString(val, 0) assert(ok) if neg { mant.Neg(mant) } if p.lit == "p" { // exponent (base 2) p.next() neg, val = p.parseInt() exp64, err := strconv.ParseUint(val, 10, 0) if err != nil { p.error(err) } exp := uint(exp64) if neg { denom := big.NewInt(1) denom.Lsh(denom, exp) x.typ = Typ[UntypedFloat] x.val = normalizeRatConst(new(big.Rat).SetFrac(mant, denom)) return } if exp > 0 { mant.Lsh(mant, exp) } x.typ = Typ[UntypedFloat] x.val = normalizeIntConst(mant) return } x.typ = Typ[UntypedInt] x.val = normalizeIntConst(mant) return }
// bigIntExp is the "op" for exp on *big.Int. Different signature for Exp means we can't use *big.Exp directly. // Also we need a context (really a config); see the bigIntExpOp function below. // We know this is not 0**negative. func bigIntExp(c Context, i, j, k *big.Int) *big.Int { if j.Cmp(bigOne.Int) == 0 || j.Sign() == 0 { return i.Set(j) } // -1ⁿ is just parity. if j.Cmp(bigMinusOne.Int) == 0 { if k.And(k, bigOne.Int).Int64() == 0 { return i.Neg(j) } return i.Set(j) } // Large exponents can be very expensive. // First, it must fit in an int64. if k.BitLen() > 63 { Errorf("%s**%s: exponent too large", j, k) } exp := k.Int64() if exp < 0 { exp = -exp } mustFit(c.Config(), int64(j.BitLen())*exp) i.Exp(j, k, nil) return i }
// Sign computes a group signature of digest using the given hash function. func (mem *MemberKey) Sign(r io.Reader, digest []byte, hashFunc hash.Hash) ([]byte, error) { var rnds [7]*big.Int for i := range rnds { var err error rnds[i], err = randomZp(r) if err != nil { return nil, err } } alpha := rnds[0] beta := rnds[1] t1 := new(bn256.G1).ScalarMult(mem.u, alpha) t2 := new(bn256.G1).ScalarMult(mem.v, beta) tmp := new(big.Int).Add(alpha, beta) t3 := new(bn256.G1).ScalarMult(mem.h, tmp) t3.Add(t3, mem.a) delta1 := new(big.Int).Mul(mem.x, alpha) delta1.Mod(delta1, bn256.Order) delta2 := new(big.Int).Mul(mem.x, beta) delta2.Mod(delta2, bn256.Order) ralpha := rnds[2] rbeta := rnds[3] rx := rnds[4] rdelta1 := rnds[5] rdelta2 := rnds[6] r1 := new(bn256.G1).ScalarMult(mem.u, ralpha) r2 := new(bn256.G1).ScalarMult(mem.v, rbeta) r3 := bn256.Pair(t3, mem.g2) r3.ScalarMult(r3, rx) tmp.Neg(ralpha) tmp.Sub(tmp, rbeta) tmp.Mod(tmp, bn256.Order) tmpgt := new(bn256.GT).ScalarMult(mem.ehw, tmp) r3.Add(r3, tmpgt) tmp.Neg(rdelta1) tmp.Sub(tmp, rdelta2) tmp.Mod(tmp, bn256.Order) tmpgt.ScalarMult(mem.ehg2, tmp) r3.Add(r3, tmpgt) r4 := new(bn256.G1).ScalarMult(t1, rx) tmp.Neg(rdelta1) tmp.Add(tmp, bn256.Order) tmpg := new(bn256.G1).ScalarMult(mem.u, tmp) r4.Add(r4, tmpg) r5 := new(bn256.G1).ScalarMult(t2, rx) tmp.Neg(rdelta2) tmp.Add(tmp, bn256.Order) tmpg.ScalarMult(mem.v, tmp) r5.Add(r5, tmpg) t1Bytes := t1.Marshal() t2Bytes := t2.Marshal() t3Bytes := t3.Marshal() hashFunc.Reset() hashFunc.Write(digest) hashFunc.Write(t1Bytes) hashFunc.Write(t2Bytes) hashFunc.Write(t3Bytes) hashFunc.Write(r1.Marshal()) hashFunc.Write(r2.Marshal()) hashFunc.Write(r3.Marshal()) hashFunc.Write(r4.Marshal()) hashFunc.Write(r5.Marshal()) c := new(big.Int).SetBytes(hashFunc.Sum(nil)) c.Mod(c, bn256.Order) salpha := new(big.Int).Mul(c, alpha) salpha.Add(salpha, ralpha) salpha.Mod(salpha, bn256.Order) sbeta := new(big.Int).Mul(c, beta) sbeta.Add(sbeta, rbeta) sbeta.Mod(sbeta, bn256.Order) sx := new(big.Int).Mul(c, mem.x) sx.Add(sx, rx) sx.Mod(sx, bn256.Order) sdelta1 := new(big.Int).Mul(c, delta1) sdelta1.Add(sdelta1, rdelta1) sdelta1.Mod(sdelta1, bn256.Order) sdelta2 := new(big.Int).Mul(c, delta2) sdelta2.Add(sdelta2, rdelta2) sdelta2.Mod(sdelta2, bn256.Order) sig := make([]byte, 0, SignatureSize) sig = append(sig, t1Bytes...) sig = append(sig, t2Bytes...) sig = append(sig, t3Bytes...) sig = appendN(sig, c) sig = appendN(sig, salpha) sig = appendN(sig, sbeta) sig = appendN(sig, sx) sig = appendN(sig, sdelta1) sig = appendN(sig, sdelta2) return sig, nil }
func (self *Decoder) load_value() interface{} { for { control, err := self.reader.ReadByte() self.store_err(err) if err != nil { return nil } self.readcount++ ctrlhi := control & 0xf0 switch ctrlhi { // Special values case 0x00: switch control { case 0x00, 0x01: return nil case 0x02: return false case 0x03: return true case 0x0f: { json_literal := self.load_value() if s, ok := json_literal.(string); ok { var result interface{} self.store_err(json.Unmarshal([]byte(s), &result)) return result } else { self.store_err(&SyntaxError{ "jksn: JKSN value 0x0f requires a string but found: " + reflect.TypeOf(json_literal).String(), self.readcount, }) } } } // Integers case 0x10: switch control { default: self.lastint = big.NewInt(int64(control & 0xf)) case 0x1b: self.lastint = self.unsigned_to_signed(self.decode_int(4), 32) case 0x1c: self.lastint = self.unsigned_to_signed(self.decode_int(2), 16) case 0x1d: self.lastint = self.unsigned_to_signed(self.decode_int(1), 8) case 0x1e: self.lastint = self.decode_int(0) self.lastint = self.lastint.Neg(self.lastint) case 0x1f: self.lastint = self.decode_int(0) } return new(big.Int).Set(self.lastint) // Floating point numbers case 0x20: switch control { case 0x20: return math.NaN() case 0x2b: self.store_err(&UnmarshalTypeError{ "float80", reflect.TypeOf(0), self.readcount, }) return math.NaN() case 0x2c: { var result float64 self.store_err(binary.Read(self.reader, binary.BigEndian, &result)) self.readcount += 8 return result } case 0x2d: { var result float32 self.store_err(binary.Read(self.reader, binary.BigEndian, &result)) self.readcount += 4 return result } case 0x2e: return math.Inf(-1) case 0x2f: return math.Inf(1) } // UTF-16 strings case 0x30: switch control { default: return self.load_string_utf16le(uint(control & 0xf)) case 0x3c: { hashvalue, err := self.reader.ReadByte() self.store_err(err) if err != nil { return "" } self.readcount++ if self.texthash[hashvalue] != nil { return *self.texthash[hashvalue] } else { self.store_err(&SyntaxError{ fmt.Sprintf("JKSN stream requires a non-existing hash: 0x%02x", hashvalue), self.readcount, }) return "" } } case 0x3d: return self.load_string_utf16le(uint(self.decode_int(2).Uint64())) case 0x3e: return self.load_string_utf16le(uint(self.decode_int(1).Uint64())) case 0x3f: return self.load_string_utf16le(uint(self.decode_int(0).Uint64())) } // UTF-8 strings case 0x40: switch control { default: return self.load_string_utf8(uint(control & 0xf)) case 0x4d: return self.load_string_utf8(uint(self.decode_int(2).Uint64())) case 0x4e: return self.load_string_utf8(uint(self.decode_int(1).Uint64())) case 0x4f: return self.load_string_utf8(uint(self.decode_int(0).Uint64())) } // Blob strings case 0x50: switch control { default: return self.load_bytes(uint(control & 0xf)) case 0x5c: { hashvalue, err := self.reader.ReadByte() self.store_err(err) if err != nil { return "" } self.readcount++ if self.blobhash[hashvalue] != nil { result := make([]byte, len(self.blobhash[hashvalue])) copy(result, self.blobhash[hashvalue]) return result } else { self.store_err(&SyntaxError{ fmt.Sprintf("JKSN stream requires a non-existing hash: 0x%02x", hashvalue), self.readcount, }) return []byte("") } } case 0x5d: return self.load_bytes(uint(self.decode_int(2).Uint64())) case 0x5e: return self.load_bytes(uint(self.decode_int(1).Uint64())) case 0x5f: return self.load_bytes(uint(self.decode_int(0).Uint64())) } // Hashtable refreshers case 0x70: switch control { case 0x70: for i := range self.texthash { self.texthash[i] = nil } for i := range self.blobhash { self.blobhash[i] = nil } default: { count := control & 0xf for count != 0 { self.load_value() count-- } } case 0x7d: { count := self.decode_int(2).Uint64() for count != 0 { self.load_value() count-- } } case 0x7e: { count := self.decode_int(1).Uint64() for count != 0 { self.load_value() count-- } } case 0x7f: { count := self.decode_int(0) one := big.NewInt(1) for count.Sign() > 0 { self.load_value() count.Sub(count, one) } } } continue // Arrays case 0x80: { var length uint64 switch control { default: length = uint64(control & 0xf) case 0x8d: length = self.decode_int(2).Uint64() case 0x8e: length = self.decode_int(1).Uint64() case 0x8f: length = self.decode_int(0).Uint64() } result := make([]interface{}, length) for i := range result { result[i] = self.load_value() } return result } // Objects case 0x90: { var length uint64 switch control { default: length = uint64(control & 0xf) case 0x9d: length = self.decode_int(2).Uint64() case 0x9e: length = self.decode_int(1).Uint64() case 0x9f: length = self.decode_int(0).Uint64() } result := make(map[interface{}]interface{}, length) for i := uint64(0); i < length; i++ { key := self.load_value() result[key] = self.load_value() } return result } // Row-col swapped arrays case 0xa0: { var length uint switch control { case 0xa0: return unspecified_value default: length = uint(control & 0xf) case 0xad: length = uint(self.decode_int(2).Uint64()) case 0xae: length = uint(self.decode_int(1).Uint64()) case 0xaf: length = uint(self.decode_int(0).Uint64()) } return self.load_swapped_array(length) } case 0xc0: switch control { // Lengthless arrays case 0xc8: { result := make([]interface{}, 0) for { item := self.load_value() switch item.(type) { default: result = append(result, item) case unspecified: return result } } } // Padding byte case 0xca: continue } // Delta encoded integers case 0xd0: { var delta *big.Int switch control { case 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5: delta = big.NewInt(int64(control & 0xf)) case 0xd6, 0xd7, 0xd8, 0xd9, 0xda: delta = big.NewInt(int64(control&0xf) - 11) case 0xdb: delta = self.decode_int(4) case 0xdc: delta = self.decode_int(2) case 0xdd: delta = self.decode_int(1) case 0xde: delta = self.decode_int(0) delta.Neg(delta) case 0xdf: delta = self.decode_int(0) } if self.lastint != nil { self.lastint.Add(self.lastint, delta) return new(big.Int).Set(self.lastint) } else { self.store_err(&SyntaxError{ "JKSN stream contains an invalid delta encoded integer", self.readcount, }) return new(big.Int) } } case 0xf0: if control <= 0xf5 { switch control { case 0xf0: self.reader.Discard(1) self.readcount++ case 0xf1: self.reader.Discard(4) self.readcount += 4 case 0xf2: self.reader.Discard(16) self.readcount += 16 case 0xf3: self.reader.Discard(20) self.readcount += 20 case 0xf4: self.reader.Discard(32) self.readcount += 32 case 0xf5: self.reader.Discard(64) self.readcount += 64 } continue } else if control >= 0xf8 && control <= 0xfd { result := self.load_value() switch control { case 0xf8: self.reader.Discard(1) self.readcount++ case 0xf9: self.reader.Discard(4) self.readcount += 4 case 0xfa: self.reader.Discard(16) self.readcount += 16 case 0xfb: self.reader.Discard(20) self.readcount += 20 case 0xfc: self.reader.Discard(32) self.readcount += 32 case 0xfd: self.reader.Discard(64) self.readcount += 64 } return result } else if control == 0xff { self.load_value() continue } } self.store_err(&SyntaxError{ fmt.Sprintf("jksn: cannot decode JKSN from byte 0x%02x", control), self.readcount - 1, }) return nil } }
// Generates P = (x-a) for the given a func xMinusConst(a *big.Int) Poly { b := new(big.Int) b.Neg(a) return Poly{b, big.NewInt(1)} }
// Verify verifies that sig is a valid signature of digest using the given hash // function. func (g *Group) Verify(digest []byte, hashFunc hash.Hash, sig []byte) bool { if len(sig) != SignatureSize { return false } t1, ok := new(bn256.G1).Unmarshal(sig[:2*32]) if !ok { return false } t2, ok := new(bn256.G1).Unmarshal(sig[2*32 : 4*32]) if !ok { return false } t3, ok := new(bn256.G1).Unmarshal(sig[4*32 : 6*32]) if !ok { return false } c := new(big.Int).SetBytes(sig[6*32 : 7*32]) salpha := new(big.Int).SetBytes(sig[7*32 : 8*32]) sbeta := new(big.Int).SetBytes(sig[8*32 : 9*32]) sx := new(big.Int).SetBytes(sig[9*32 : 10*32]) sdelta1 := new(big.Int).SetBytes(sig[10*32 : 11*32]) sdelta2 := new(big.Int).SetBytes(sig[11*32 : 12*32]) r1 := new(bn256.G1).ScalarMult(g.u, salpha) tmp := new(big.Int).Neg(c) tmp.Add(tmp, bn256.Order) tmpg := new(bn256.G1).ScalarMult(t1, tmp) r1.Add(r1, tmpg) r2 := new(bn256.G1).ScalarMult(g.v, sbeta) tmpg.ScalarMult(t2, tmp) r2.Add(r2, tmpg) r4 := new(bn256.G1).ScalarMult(t1, sx) tmp.Neg(sdelta1) tmp.Add(tmp, bn256.Order) tmpg.ScalarMult(g.u, tmp) r4.Add(r4, tmpg) r5 := new(bn256.G1).ScalarMult(t2, sx) tmp.Neg(sdelta2) tmp.Add(tmp, bn256.Order) tmpg.ScalarMult(g.v, tmp) r5.Add(r5, tmpg) r3 := bn256.Pair(t3, g.g2) r3.ScalarMult(r3, sx) tmp.Neg(salpha) tmp.Sub(tmp, sbeta) tmp.Mod(tmp, bn256.Order) tmpgt := new(bn256.GT).ScalarMult(g.ehw, tmp) r3.Add(r3, tmpgt) tmp.Neg(sdelta1) tmp.Sub(tmp, sdelta2) tmp.Mod(tmp, bn256.Order) tmpgt.ScalarMult(g.ehg2, tmp) r3.Add(r3, tmpgt) et3w := bn256.Pair(t3, g.w) et3w.Add(et3w, g.minusEg1g2) et3w.ScalarMult(et3w, c) r3.Add(r3, et3w) hashFunc.Reset() hashFunc.Write(digest) hashFunc.Write(t1.Marshal()) hashFunc.Write(t2.Marshal()) hashFunc.Write(t3.Marshal()) hashFunc.Write(r1.Marshal()) hashFunc.Write(r2.Marshal()) hashFunc.Write(r3.Marshal()) hashFunc.Write(r4.Marshal()) hashFunc.Write(r5.Marshal()) cprime := new(big.Int).SetBytes(hashFunc.Sum(nil)) cprime.Mod(cprime, bn256.Order) return cprime.Cmp(c) == 0 }
// Post-order traversal, equivalent to postfix notation. func Eval(node interface{}) (*big.Int, error) { switch nn := node.(type) { case *ast.BinaryExpr: z := new(big.Int) x, xerr := Eval(nn.X) if xerr != nil { return nil, xerr } y, yerr := Eval(nn.Y) if yerr != nil { return nil, yerr } switch nn.Op { case token.ADD: return z.Add(x, y), nil case token.SUB: return z.Sub(x, y), nil case token.MUL: return z.Mul(x, y), nil case token.QUO: if y.Sign() == 0 { // 0 denominator return nil, DivideByZero } return z.Quo(x, y), nil case token.REM: if y.Sign() == 0 { return nil, DivideByZero } return z.Rem(x, y), nil case token.AND: return z.And(x, y), nil case token.OR: return z.Or(x, y), nil case token.XOR: return z.Xor(x, y), nil case token.SHL: if y.Sign() < 0 { // negative shift return nil, NegativeShift } return z.Lsh(x, uint(y.Int64())), nil case token.SHR: if y.Sign() < 0 { return nil, NegativeShift } return z.Rsh(x, uint(y.Int64())), nil case token.AND_NOT: return z.AndNot(x, y), nil default: return nil, UnknownOpErr } case *ast.UnaryExpr: var z *big.Int var err error if z, err = Eval(nn.X); err != nil { return nil, err } switch nn.Op { case token.SUB: // -x return z.Neg(z), nil case token.XOR: // ^x return z.Not(z), nil case token.ADD: // +x (useless) return z, nil } case *ast.BasicLit: z := new(big.Int) switch nn.Kind { case token.INT: z.SetString(nn.Value, 0) return z, nil default: return nil, UnknownLitErr } case *ast.ParenExpr: z, err := Eval(nn.X) if err != nil { return nil, err } return z, nil case *ast.CallExpr: ident, ok := nn.Fun.(*ast.Ident) if !ok { return nil, UnknownTokenErr // quarter to four am; dunno correct error } var f Func f, ok = FuncMap[ident.Name] if !ok { return nil, UnknownFuncErr } var aerr error args := make([]*big.Int, len(nn.Args)) for i, a := range nn.Args { if args[i], aerr = Eval(a); aerr != nil { return nil, aerr } } x, xerr := f(args...) if xerr != nil { return nil, xerr } return x, nil } return nil, UnknownTokenErr }
// 3f 80 80 01 UNIVERSAL 1 (BOOLEAN), CONSTRUCTED // returns the index of the next undecoded byte func analyseDER(der []byte, idx int, indent string, output *[]string) int { for idx < len(der) { *output = append(*output, indent) tag := int(der[idx]) *output = append(*output, fmt.Sprintf("%02X", tag)) class := tag & (128 + 64) constructed := (tag & 32) != 0 tagnum := tag & 31 if tagnum == 31 { tagnum = 0 for { idx++ if idx == len(der) { *output = append(*output, prematureEnd) return idx } *output = append(*output, fmt.Sprintf(" %02X", der[idx])) tagnum = (tagnum << 7) + int(der[idx]&127) if der[idx]&128 == 0 { break } if tagnum > 0xFFFFFF { // arbitrary cutoff for tag sizes to prevent overflow of tagnum *output = append(*output, " !TAG OUT OF RANGE!") return idx } } } classstr := TagClass[class] if classstr == "" { classstr = "CONTEXT-SPECIFIC " } *output = append(*output, fmt.Sprintf(" %v%v", classstr, tagnum)) if class == 0 && tagnum > 0 && tagnum < 31 { // UNIVERSAL (except 0 which is reserved) *output = append(*output, fmt.Sprintf(" (%v)", UniversalTagName[tagnum])) } if constructed { *output = append(*output, " CONSTRUCTED") } else { *output = append(*output, " PRIMITIVE") } *output = append(*output, "\n") idx++ if idx == len(der) { *output = append(*output, prematureEnd) return idx } *output = append(*output, fmt.Sprintf("%v%02X", indent, der[idx])) length := int(der[idx]) if length <= 127 { *output = append(*output, fmt.Sprintf(" LENGTH %v", length)) } else { length &= 127 if length == 0 { // indefinite length length = -1 if !constructed { *output = append(*output, fmt.Sprintf(" !PRIMITIVE ENCODING WITH INDEFINITE LENGTH!")) return idx } *output = append(*output, fmt.Sprintf(" INDEFINITE LENGTH")) } else { if length > 3 { // reject data structures larger than 16MB (or incorrectly encoded length) *output = append(*output, " !TOO MANY LENGTH OCTETS!") return idx } l := 0 for length > 0 { idx++ if idx == len(der) { *output = append(*output, prematureEnd) return idx } *output = append(*output, fmt.Sprintf(" %02X", der[idx])) l = (l << 8) + int(der[idx]) length-- } length = l *output = append(*output, fmt.Sprintf(" LENGTH %v", length)) } } if tag == 0 && length == 0 { // end of contents marker return idx + 1 } *output = append(*output, "\n") if constructed { idx++ if length < 0 { // indefinite length idx = analyseDER(der, idx, indent+indentStep, output) } else if idx+length > len(der) { // length exceeds available data *output = append(*output, " !LENGTH EXCEEDS AVAILABLE DATA!") } else { idx2 := analyseDER(der[0:idx+length], idx, indent+indentStep, output) if idx2 != idx+length { *output = append(*output, " !SHORT DATA!") } idx = idx2 } // if a decoding error occurred, do not continue if strings.HasSuffix((*output)[len(*output)-1], "!") { return idx } } else { // primitive *output = append(*output, indent) if length == 0 { *output = append(*output, "EMPTY ") } contents := "" already_decoded := false decoding := []string{} if length > 0 && idx+length < len(der) && ((tag&(128+64) == 128) || tag == 19 || tag == 4 || tag == 6 || tag == 12 || tag == 23 || tag == 22 || tag == 2) { cont := der[idx+1 : idx+1+length] if tag == 2 { // INTEGER var b big.Int b.SetBytes(cont) if cont[0]&128 != 0 { // negative number var x big.Int x.SetBit(&x, len(cont)*8, 1) x.Sub(&x, &b) b.Neg(&x) } contents = " " + b.String() } if contents == "" && (tag == 4 || tag > 31) { // try to parse as DER idx2 := analyseDER(cont, 0, indent+indentStep, &decoding) if idx2 == len(cont) && len(decoding) > 0 && !strings.HasSuffix(decoding[len(decoding)-1], "!") { contents = " ARE VALID DER => DECODING\n" already_decoded = true length -= len(cont) idx += len(cont) } } if contents == "" && tag != 6 && length < 80 { // try to parse as string contents = fmt.Sprintf(" %q", cont) if strings.Contains(contents, `\x`) { contents = "" } } if contents == "" && (tag == 6 || (length < 16 && length >= 4)) { // Try to parse as OID contents = " " + oidString(cont) if strings.HasSuffix(contents, "!") { contents = "" } } } // no else for error reporting here because error will be reported further below for !already_decoded && length > 0 { idx++ if idx == len(der) { *output = append(*output, prematureEnd) return idx } *output = append(*output, fmt.Sprintf("%02X ", der[idx])) length-- } *output = append(*output, "CONTENTS") if contents != "" { *output = append(*output, contents) } if already_decoded { *output = append(*output, decoding...) } else { *output = append(*output, "\n") } idx++ } } return idx }