mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-11 17:28:08 +00:00
feat: 添加 Lighter 适配器及相关功能,支持 trailing stops 和新的交易逻辑
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
package signature
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
curve "github.com/elliottech/poseidon_crypto/curve/ecgfp5"
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
gFp5 "github.com/elliottech/poseidon_crypto/field/goldilocks_quintic_extension"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
type Signature struct {
|
||||
S curve.ECgFp5Scalar
|
||||
E curve.ECgFp5Scalar
|
||||
}
|
||||
|
||||
type NumericalSignature [10]uint64
|
||||
|
||||
func (s Signature) ToNumericalSignature() NumericalSignature {
|
||||
return NumericalSignature{
|
||||
s.S[0], s.S[1], s.S[2], s.S[3], s.S[4],
|
||||
s.E[0], s.E[1], s.E[2], s.E[3], s.E[4],
|
||||
}
|
||||
}
|
||||
|
||||
func (s Signature) DeepCopy() Signature {
|
||||
return Signature{
|
||||
S: s.S.DeepCopy(),
|
||||
E: s.E.DeepCopy(),
|
||||
}
|
||||
}
|
||||
|
||||
// (s little endian) || (e little endian)
|
||||
func (s Signature) ToBytes() []byte {
|
||||
sBytes := s.S.ToLittleEndianBytes()
|
||||
eBytes := s.E.ToLittleEndianBytes()
|
||||
res := make([]byte, 80)
|
||||
copy(res[:40], sBytes[:])
|
||||
copy(res[40:], eBytes[:])
|
||||
return res
|
||||
}
|
||||
|
||||
func SigFromBytes(b []byte) (Signature, error) {
|
||||
if len(b) != 80 {
|
||||
return ZERO_SIG, fmt.Errorf("signature length should be 80 but is %d", len(b))
|
||||
}
|
||||
|
||||
return Signature{
|
||||
S: curve.ScalarElementFromLittleEndianBytes(b[:40]),
|
||||
E: curve.ScalarElementFromLittleEndianBytes(b[40:]),
|
||||
}, nil
|
||||
}
|
||||
|
||||
var ZERO_SIG = Signature{
|
||||
S: curve.ZERO,
|
||||
E: curve.ZERO,
|
||||
}
|
||||
|
||||
var ONE_SK = curve.ONE
|
||||
|
||||
// Public key is actually an EC point (4 Fp5 elements), but it can be encoded as a single Fp5 element.
|
||||
func SchnorrPkFromSk(sk curve.ECgFp5Scalar) gFp5.Element {
|
||||
return curve.GENERATOR_ECgFp5Point.Mul(&sk).Encode()
|
||||
}
|
||||
|
||||
func SchnorrSignHashedMessage(hashedMsg gFp5.Element, sk curve.ECgFp5Scalar) Signature {
|
||||
// Sample random scalar `k` and compute `r = k * G`
|
||||
k := curve.SampleScalarCrypto()
|
||||
r := curve.GENERATOR_ECgFp5Point.Mul(&k).Encode()
|
||||
|
||||
// Compute `e = H(r || H(m))`, which is a scalar point
|
||||
preImage := make([]g.Element, 5+5)
|
||||
for i, elem := range r.ToBasefieldArray() {
|
||||
preImage[i] = elem
|
||||
}
|
||||
for i, elem := range hashedMsg.ToBasefieldArray() {
|
||||
preImage[i+5] = elem
|
||||
}
|
||||
|
||||
e := curve.FromGfp5(p2.HashToQuinticExtension(preImage))
|
||||
return Signature{
|
||||
S: k.Sub(*e.Mul(&sk)),
|
||||
E: e,
|
||||
}
|
||||
}
|
||||
|
||||
func SchnorrSignHashedMessage2(hashedMsg gFp5.Element, sk, k curve.ECgFp5Scalar) Signature {
|
||||
r := curve.GENERATOR_ECgFp5Point.Mul(&k).Encode()
|
||||
// Compute `e = H(r || H(m))`, which is a scalar point
|
||||
preImage := make([]g.Element, 5+5)
|
||||
for i, elem := range r.ToBasefieldArray() {
|
||||
preImage[i] = elem
|
||||
}
|
||||
for i, elem := range hashedMsg.ToBasefieldArray() {
|
||||
preImage[i+5] = elem
|
||||
}
|
||||
|
||||
e := curve.FromGfp5(p2.HashToQuinticExtension(preImage))
|
||||
return Signature{
|
||||
S: k.Sub(*e.Mul(&sk)),
|
||||
E: e,
|
||||
}
|
||||
}
|
||||
|
||||
func Validate(pubKey, hashedMsg, sig []byte) error {
|
||||
pk, err := gFp5.FromCanonicalLittleEndianBytes(pubKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert public key bytes to field element: %w", err)
|
||||
}
|
||||
hashedMsgElem, err := gFp5.FromCanonicalLittleEndianBytes(hashedMsg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert hashed message bytes to field element: %w", err)
|
||||
}
|
||||
s, err := SigFromBytes(sig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert signature bytes to Schnorr signature: %w", err)
|
||||
}
|
||||
|
||||
valid := IsSchnorrSignatureValid(&pk, &hashedMsgElem, s)
|
||||
if !valid {
|
||||
return fmt.Errorf("signature is invalid")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsSchnorrSignatureValid(pubKey, hashedMsg *gFp5.Element, sig Signature) bool {
|
||||
pubKeyWs, ok := curve.DecodeFp5AsWeierstrass(*pubKey)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rV := curve.MulAdd2(curve.GENERATOR_WEIERSTRASS, pubKeyWs, sig.S, sig.E).Encode() // r_v = s*G + e*pk
|
||||
|
||||
preImage := make([]g.Element, 5+5)
|
||||
for i, elem := range rV.ToBasefieldArray() {
|
||||
preImage[i] = elem
|
||||
}
|
||||
for i, elem := range hashedMsg.ToBasefieldArray() {
|
||||
preImage[i+5] = elem
|
||||
}
|
||||
eV := curve.FromGfp5(p2.HashToQuinticExtension(preImage))
|
||||
|
||||
return eV.Equals(&sig.E) // e_v == e
|
||||
}
|
||||
Reference in New Issue
Block a user