func FuncOP_CHECKSIG(s *Stack, data *Data) error { if data == nil || data.Hasher == nil { return fmt.Errorf("Requires a hasher.") } pk, err := s.PopData() if err != nil { return err } x, y, err := utils.ParsePublicKey(pk) if err != nil { return fmt.Errorf("Failed to parse public key: %v", err) } pubKey := bitecdsa.PublicKey{bitelliptic.S256(), x, y} sn, err := s.PopData() if err != nil { return err } sign, hashCode := sn[:len(sn)-1], sn[len(sn)-1] R, S, err := utils.DERDecode(sign) if err != nil { return fmt.Errorf("Failed to parse signature: %v", err) } hash := data.Hasher(uint32(hashCode)) if bitecdsa.Verify(&pubKey, hash, R, S) { s.PushBool(true) } else { s.PushBool(false) } return nil }
func ParseCompact(b []byte) (*big.Int, *big.Int, error) { if len(b) != 33 { return nil, nil, fmt.Errorf("Data \"%x\" isn't 33 bytes.", b) } curve := bitelliptic.S256() // y = sqrt(x^3 + B) mod P x := new(big.Int).SetBytes(b[1:33]) x3 := new(big.Int).Mul(x, x) x3.Mul(x3, x) y2 := new(big.Int).Add(x3, curve.B) y2.Mod(y2, curve.P) // sqrt(a) = a^((P+1)/4) e := big.NewInt(1) e = e.Add(e, curve.P) e = e.Div(e, big.NewInt(4)) y := y2.Exp(y2, e, curve.P) switch b[0] { case 0x02: // y should be even. if y.Bit(0) == 1 { y = y.Sub(curve.P, y) } case 0x03: // y should be odd. if y.Bit(0) == 0 { y = y.Sub(curve.P, y) } default: // TODO consider panicking if functions is private. return nil, nil, fmt.Errorf("Bad prefix 0x%x.", b[0]) } return x, y, nil }