From 0a8bad46b58ea2167ecc9f1d39b46ffc63f4801c Mon Sep 17 00:00:00 2001 From: tsingbx Date: Thu, 8 Aug 2024 08:31:03 +0800 Subject: [PATCH 1/4] add big.Int Set, Abs, Neg and add test it --- _cmptest/bigintdemo/fib.go | 29 ++++++++- internal/lib/math/big/int.go | 119 +++++++++++++++++++++++++++++++---- 2 files changed, 134 insertions(+), 14 deletions(-) diff --git a/_cmptest/bigintdemo/fib.go b/_cmptest/bigintdemo/fib.go index 9876c2e0..0b4658ba 100644 --- a/_cmptest/bigintdemo/fib.go +++ b/_cmptest/bigintdemo/fib.go @@ -5,7 +5,7 @@ import ( "math/big" ) -func main() { +func fib() { // Initialize two big ints with the first two numbers in the sequence. a := big.NewInt(0) b := big.NewInt(1) @@ -23,3 +23,30 @@ func main() { } fmt.Println(a) // 100-digit Fibonacci number } + +func abs() { + a := big.NewInt(64) + b := big.NewInt(-52) + a.Set(b) + a.Abs(a) + a.Set(big.NewInt(-164)) + a.Abs(a) + fmt.Println("value: ", a.String()) +} + +func neg() { + fmt.Println("value: ", big.NewInt(-64).Neg(big.NewInt(-64))) + fmt.Println("value: ", big.NewInt(64).Neg(big.NewInt(64))) + fmt.Println("value: ", big.NewInt(0).Neg(big.NewInt(0))) +} + +func main() { + a := big.NewInt(64) + b := big.NewInt(-52) + c := big.NewInt(54) + fmt.Println("value:", a.Add(a, b)) + fmt.Println("value:", a.Sub(b, c)) + d := big.NewInt(10) + e := big.NewInt(4) + fmt.Println("value:", d.Mul(d, e)) +} diff --git a/internal/lib/math/big/int.go b/internal/lib/math/big/int.go index f568938b..02341907 100644 --- a/internal/lib/math/big/int.go +++ b/internal/lib/math/big/int.go @@ -81,9 +81,35 @@ func NewInt(x int64) *Int { return z.SetInt64(x) } -/* // Set sets z to x and returns z. func (z *Int) Set(x *Int) *Int { + if z != x { + a := (*openssl.BIGNUM)(z) + b := (*openssl.BIGNUM)(x) + a.SetWord(b.GetWord()) + a.SetNegative(b.IsNegative()) + } + return z +} + +// Abs sets z to |x| (the absolute value of x) and returns z. +func (z *Int) Abs(x *Int) *Int { + z.Set(x) + a := (*openssl.BIGNUM)(z) + a.SetNegative(0) + return z +} + +// Neg sets z to -x and returns z. +func (z *Int) Neg(x *Int) *Int { + z.Set(x) + a := (*openssl.BIGNUM)(z) + if a.IsNegative() != 0 { + a.SetNegative(0) + } else { + a.SetNegative(1) + } + return z } // Bits provides raw (unchecked but fast) access to x by returning its @@ -92,6 +118,7 @@ func (z *Int) Set(x *Int) *Int { // Bits is intended to support implementation of missing low-level Int // functionality outside this package; it should be avoided otherwise. func (x *Int) Bits() []Word { + panic("big.Bits") } // SetBits provides raw (unchecked but fast) access to z by setting its @@ -100,17 +127,9 @@ func (x *Int) Bits() []Word { // SetBits is intended to support implementation of missing low-level Int // functionality outside this package; it should be avoided otherwise. func (z *Int) SetBits(abs []Word) *Int { + panic("big.SetBits") } -// Abs sets z to |x| (the absolute value of x) and returns z. -func (z *Int) Abs(x *Int) *Int { -} - -// Neg sets z to -x and returns z. -func (z *Int) Neg(x *Int) *Int { -} -*/ - // Add sets z to the sum x+y and returns z. func (z *Int) Add(x, y *Int) *Int { (*openssl.BIGNUM)(z).Add((*openssl.BIGNUM)(x), (*openssl.BIGNUM)(y)) @@ -123,31 +142,100 @@ func (z *Int) Sub(x, y *Int) *Int { return z } -/* // Mul sets z to the product x*y and returns z. func (z *Int) Mul(x, y *Int) *Int { + a := (*openssl.BIGNUM)(z) + xx := (*openssl.BIGNUM)(x) + yy := (*openssl.BIGNUM)(y) + a.Mul(a, xx, yy, ctxGet()) + return z } // MulRange sets z to the product of all integers // in the range [a, b] inclusively and returns z. // If a > b (empty range), the result is 1. func (z *Int) MulRange(a, b int64) *Int { + switch { + case a > b: + return z.SetInt64(1) // empty range + case a <= 0 && b >= 0: + return z.SetInt64(0) // range includes 0 + } + // a <= b && (b < 0 || a > 0) + neg := false + if a < 0 { + neg = (b-a)&1 == 0 + a, b = -b, -a + } + zz := (*openssl.BIGNUM)(z) + for i := a; i < b; i++ { + zz.MulWord(openssl.BN_ULONG(i)) + } + if neg { + zz.SetNegative(1) + } else { + zz.SetNegative(0) + } + return z } // Binomial sets z to the binomial coefficient C(n, k) and returns z. func (z *Int) Binomial(n, k int64) *Int { + if k > n { + return z.SetInt64(0) + } + // reduce the number of multiplications by reducing k + if k > n-k { + k = n - k // C(n, k) == C(n, n-k) + } + // C(n, k) == n * (n-1) * ... * (n-k+1) / k * (k-1) * ... * 1 + // == n * (n-1) * ... * (n-k+1) / 1 * (1+1) * ... * k + // + // Using the multiplicative formula produces smaller values + // at each step, requiring fewer allocations and computations: + // + // z = 1 + // for i := 0; i < k; i = i+1 { + // z *= n-i + // z /= i+1 + // } + // + // finally to avoid computing i+1 twice per loop: + // + // z = 1 + // i := 0 + // for i < k { + // z *= n-i + // i++ + // z /= i + // } + var N, K, i, t Int + N.SetInt64(n) + K.SetInt64(k) + + intOne := NewInt(1) + + z.Set(intOne) + for i.Cmp(&K) < 0 { + z.Mul(z, t.Sub(&N, &i)) + i.Add(&i, intOne) + z.Quo(z, &i) + } + return z } // Quo sets z to the quotient x/y for y != 0 and returns z. // If y == 0, a division-by-zero run-time panic occurs. // Quo implements truncated division (like Go); see QuoRem for more details. func (z *Int) Quo(x, y *Int) *Int { + panic("big.Quo") } // Rem sets z to the remainder x%y for y != 0 and returns z. // If y == 0, a division-by-zero run-time panic occurs. // Rem implements truncated modulus (like Go); see QuoRem for more details. func (z *Int) Rem(x, y *Int) *Int { + panic("big.Rem") } // QuoRem sets z to the quotient x/y and r to the remainder x%y @@ -162,18 +250,21 @@ func (z *Int) Rem(x, y *Int) *Int { // (See Daan Leijen, “Division and Modulus for Computer Scientists”.) // See DivMod for Euclidean division and modulus (unlike Go). func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) { + panic("big.QuoRem") } // Div sets z to the quotient x/y for y != 0 and returns z. // If y == 0, a division-by-zero run-time panic occurs. // Div implements Euclidean division (unlike Go); see DivMod for more details. func (z *Int) Div(x, y *Int) *Int { + panic("big.Div") } // Mod sets z to the modulus x%y for y != 0 and returns z. // If y == 0, a division-by-zero run-time panic occurs. // Mod implements Euclidean modulus (unlike Go); see DivMod for more details. func (z *Int) Mod(x, y *Int) *Int { + panic("big.Mod") } // DivMod sets z to the quotient x div y and m to the modulus x mod y @@ -191,8 +282,8 @@ func (z *Int) Mod(x, y *Int) *Int { // ACM press.) // See QuoRem for T-division and modulus (like Go). func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) { + panic("big.DivMod") } -*/ // Cmp compares x and y and returns: // @@ -212,17 +303,19 @@ func (x *Int) CmpAbs(y *Int) int { return int((*openssl.BIGNUM)(x).Ucmp((*openssl.BIGNUM)(y))) } -/* // Int64 returns the int64 representation of x. // If x cannot be represented in an int64, the result is undefined. func (x *Int) Int64() int64 { + panic("big.Int64") } // Uint64 returns the uint64 representation of x. // If x cannot be represented in a uint64, the result is undefined. func (x *Int) Uint64() uint64 { + panic("big.Uint64") } +/* // IsInt64 reports whether x can be represented as an int64. func (x *Int) IsInt64() bool { } From 289caa7cc2cff3d9c528e5b643a2a89278654978 Mon Sep 17 00:00:00 2001 From: tsingbx Date: Thu, 8 Aug 2024 09:10:31 +0800 Subject: [PATCH 2/4] add BN_CTX Start, Get, End and Add big.Int Mul and test it --- c/openssl/bn.go | 11 +++++++++++ internal/lib/math/big/int.go | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/c/openssl/bn.go b/c/openssl/bn.go index 4a765b1c..225dd324 100644 --- a/c/openssl/bn.go +++ b/c/openssl/bn.go @@ -49,8 +49,19 @@ func BN_CTXSecureNew() *BN_CTX func (*BN_CTX) Free() {} // void BN_CTX_start(BN_CTX *ctx); +// +// llgo:link (*BN_CTX).Start C.BN_CTX_start +func (*BN_CTX) Start() {} + // BIGNUM *BN_CTX_get(BN_CTX *ctx); +// +// llgo:link (*BN_CTX).Get C.BN_CTX_get +func (*BN_CTX) Get() *BIGNUM { return nil } + // void BN_CTX_end(BN_CTX *ctx); +// +// llgo:link (*BN_CTX).End C.BN_CTX_end +func (*BN_CTX) End() {} // ----------------------------------------------------------------------------- diff --git a/internal/lib/math/big/int.go b/internal/lib/math/big/int.go index 02341907..f3ce8724 100644 --- a/internal/lib/math/big/int.go +++ b/internal/lib/math/big/int.go @@ -18,6 +18,8 @@ package big // llgo:skipall import ( + "sync" + "github.com/goplus/llgo/c/openssl" ) @@ -35,6 +37,18 @@ func ctxPut(ctx *openssl.BN_CTX) { ctx.Free() } +var g_lock = &sync.Mutex{} +var g_ctx *openssl.BN_CTX + +func getCtxInstance() *openssl.BN_CTX { + if g_ctx == nil { + g_lock.Lock() + defer g_lock.Unlock() + g_ctx = ctxGet() + } + return g_ctx +} + // ----------------------------------------------------------------------------- type Int openssl.BIGNUM @@ -147,7 +161,9 @@ func (z *Int) Mul(x, y *Int) *Int { a := (*openssl.BIGNUM)(z) xx := (*openssl.BIGNUM)(x) yy := (*openssl.BIGNUM)(y) - a.Mul(a, xx, yy, ctxGet()) + getCtxInstance().Start() + defer getCtxInstance().End() + a.Mul(a, xx, yy, getCtxInstance()) return z } From df37f80c8efd50331832476145cbd07eda82f16c Mon Sep 17 00:00:00 2001 From: tsingbx Date: Thu, 8 Aug 2024 13:33:14 +0800 Subject: [PATCH 3/4] add big.Int Lsh and Rsh and test it --- _cmptest/bigintdemo/fib.go | 13 +++- internal/lib/math/big/int.go | 147 ++++++++++++----------------------- 2 files changed, 60 insertions(+), 100 deletions(-) diff --git a/_cmptest/bigintdemo/fib.go b/_cmptest/bigintdemo/fib.go index 0b4658ba..23a3d5a4 100644 --- a/_cmptest/bigintdemo/fib.go +++ b/_cmptest/bigintdemo/fib.go @@ -40,7 +40,7 @@ func neg() { fmt.Println("value: ", big.NewInt(0).Neg(big.NewInt(0))) } -func main() { +func calc() { a := big.NewInt(64) b := big.NewInt(-52) c := big.NewInt(54) @@ -50,3 +50,14 @@ func main() { e := big.NewInt(4) fmt.Println("value:", d.Mul(d, e)) } + +func bitop() { + a := big.NewInt(4) + fmt.Println("value:", a.Lsh(a, 1)) + b := big.NewInt(16) + fmt.Println("value:", b.Rsh(b, 2)) +} + +func main() { + bitop() +} diff --git a/internal/lib/math/big/int.go b/internal/lib/math/big/int.go index f3ce8724..e0bbbfe1 100644 --- a/internal/lib/math/big/int.go +++ b/internal/lib/math/big/int.go @@ -18,8 +18,9 @@ package big // llgo:skipall import ( - "sync" + "math/rand" + "github.com/goplus/llgo/c" "github.com/goplus/llgo/c/openssl" ) @@ -37,18 +38,6 @@ func ctxPut(ctx *openssl.BN_CTX) { ctx.Free() } -var g_lock = &sync.Mutex{} -var g_ctx *openssl.BN_CTX - -func getCtxInstance() *openssl.BN_CTX { - if g_ctx == nil { - g_lock.Lock() - defer g_lock.Unlock() - g_ctx = ctxGet() - } - return g_ctx -} - // ----------------------------------------------------------------------------- type Int openssl.BIGNUM @@ -100,8 +89,7 @@ func (z *Int) Set(x *Int) *Int { if z != x { a := (*openssl.BIGNUM)(z) b := (*openssl.BIGNUM)(x) - a.SetWord(b.GetWord()) - a.SetNegative(b.IsNegative()) + a.Copy(b) } return z } @@ -132,7 +120,7 @@ func (z *Int) Neg(x *Int) *Int { // Bits is intended to support implementation of missing low-level Int // functionality outside this package; it should be avoided otherwise. func (x *Int) Bits() []Word { - panic("big.Bits") + panic("todo big.Bits") } // SetBits provides raw (unchecked but fast) access to z by setting its @@ -141,7 +129,7 @@ func (x *Int) Bits() []Word { // SetBits is intended to support implementation of missing low-level Int // functionality outside this package; it should be avoided otherwise. func (z *Int) SetBits(abs []Word) *Int { - panic("big.SetBits") + panic("todo big.SetBits") } // Add sets z to the sum x+y and returns z. @@ -158,100 +146,33 @@ func (z *Int) Sub(x, y *Int) *Int { // Mul sets z to the product x*y and returns z. func (z *Int) Mul(x, y *Int) *Int { - a := (*openssl.BIGNUM)(z) - xx := (*openssl.BIGNUM)(x) - yy := (*openssl.BIGNUM)(y) - getCtxInstance().Start() - defer getCtxInstance().End() - a.Mul(a, xx, yy, getCtxInstance()) - return z + panic("todo big.Mul") } // MulRange sets z to the product of all integers // in the range [a, b] inclusively and returns z. // If a > b (empty range), the result is 1. func (z *Int) MulRange(a, b int64) *Int { - switch { - case a > b: - return z.SetInt64(1) // empty range - case a <= 0 && b >= 0: - return z.SetInt64(0) // range includes 0 - } - // a <= b && (b < 0 || a > 0) - neg := false - if a < 0 { - neg = (b-a)&1 == 0 - a, b = -b, -a - } - zz := (*openssl.BIGNUM)(z) - for i := a; i < b; i++ { - zz.MulWord(openssl.BN_ULONG(i)) - } - if neg { - zz.SetNegative(1) - } else { - zz.SetNegative(0) - } - return z + panic("todo big.MulRange") } // Binomial sets z to the binomial coefficient C(n, k) and returns z. func (z *Int) Binomial(n, k int64) *Int { - if k > n { - return z.SetInt64(0) - } - // reduce the number of multiplications by reducing k - if k > n-k { - k = n - k // C(n, k) == C(n, n-k) - } - // C(n, k) == n * (n-1) * ... * (n-k+1) / k * (k-1) * ... * 1 - // == n * (n-1) * ... * (n-k+1) / 1 * (1+1) * ... * k - // - // Using the multiplicative formula produces smaller values - // at each step, requiring fewer allocations and computations: - // - // z = 1 - // for i := 0; i < k; i = i+1 { - // z *= n-i - // z /= i+1 - // } - // - // finally to avoid computing i+1 twice per loop: - // - // z = 1 - // i := 0 - // for i < k { - // z *= n-i - // i++ - // z /= i - // } - var N, K, i, t Int - N.SetInt64(n) - K.SetInt64(k) - - intOne := NewInt(1) - - z.Set(intOne) - for i.Cmp(&K) < 0 { - z.Mul(z, t.Sub(&N, &i)) - i.Add(&i, intOne) - z.Quo(z, &i) - } - return z + panic("todo big.Binomial") } // Quo sets z to the quotient x/y for y != 0 and returns z. // If y == 0, a division-by-zero run-time panic occurs. // Quo implements truncated division (like Go); see QuoRem for more details. func (z *Int) Quo(x, y *Int) *Int { - panic("big.Quo") + panic("todo big.Quo") } // Rem sets z to the remainder x%y for y != 0 and returns z. // If y == 0, a division-by-zero run-time panic occurs. // Rem implements truncated modulus (like Go); see QuoRem for more details. func (z *Int) Rem(x, y *Int) *Int { - panic("big.Rem") + panic("todo big.Rem") } // QuoRem sets z to the quotient x/y and r to the remainder x%y @@ -266,21 +187,21 @@ func (z *Int) Rem(x, y *Int) *Int { // (See Daan Leijen, “Division and Modulus for Computer Scientists”.) // See DivMod for Euclidean division and modulus (unlike Go). func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) { - panic("big.QuoRem") + panic("todo big.QuoRem") } // Div sets z to the quotient x/y for y != 0 and returns z. // If y == 0, a division-by-zero run-time panic occurs. // Div implements Euclidean division (unlike Go); see DivMod for more details. func (z *Int) Div(x, y *Int) *Int { - panic("big.Div") + panic("todo big.Div") } // Mod sets z to the modulus x%y for y != 0 and returns z. // If y == 0, a division-by-zero run-time panic occurs. // Mod implements Euclidean modulus (unlike Go); see DivMod for more details. func (z *Int) Mod(x, y *Int) *Int { - panic("big.Mod") + panic("todo big.Mod") } // DivMod sets z to the quotient x div y and m to the modulus x mod y @@ -322,28 +243,32 @@ func (x *Int) CmpAbs(y *Int) int { // Int64 returns the int64 representation of x. // If x cannot be represented in an int64, the result is undefined. func (x *Int) Int64() int64 { - panic("big.Int64") + panic("todo big.Int64") } // Uint64 returns the uint64 representation of x. // If x cannot be represented in a uint64, the result is undefined. func (x *Int) Uint64() uint64 { - panic("big.Uint64") + panic("todo big.Uint64") } -/* // IsInt64 reports whether x can be represented as an int64. func (x *Int) IsInt64() bool { + panic("todo big.IsInt64") } // IsUint64 reports whether x can be represented as a uint64. func (x *Int) IsUint64() bool { + panic("todo big.IsUint64") } // Float64 returns the float64 value nearest x, // and an indication of any rounding that occurred. // TODO(xsw): -// func (x *Int) Float64() (float64, Accuracy) +/* +func (x *Int) Float64() (float64, Accuracy) { + panic("todo big.Float64") +}*/ // SetString sets z to the value of s, interpreted in the given base, // and returns z and a boolean indicating success. The entire string @@ -368,17 +293,20 @@ func (x *Int) IsUint64() bool { // are no other errors. If base != 0, underscores are not recognized // and act like any other character that is not a valid digit. func (z *Int) SetString(s string, base int) (*Int, bool) { + panic("todo big.SetString") } // SetBytes interprets buf as the bytes of a big-endian unsigned // integer, sets z to that value, and returns z. func (z *Int) SetBytes(buf []byte) *Int { + panic("todo big.SetBytes") } // Bytes returns the absolute value of x as a big-endian byte slice. // // To use a fixed length slice, or a preallocated one, use FillBytes. func (x *Int) Bytes() []byte { + panic("todo big.Bytes") } // FillBytes sets buf to the absolute value of x, storing it as a zero-extended @@ -386,18 +314,20 @@ func (x *Int) Bytes() []byte { // // If the absolute value of x doesn't fit in buf, FillBytes will panic. func (x *Int) FillBytes(buf []byte) []byte { + panic("todo big.FillBytes") } // BitLen returns the length of the absolute value of x in bits. // The bit length of 0 is 0. func (x *Int) BitLen() int { + panic("todo big.BitLen") } // TrailingZeroBits returns the number of consecutive least significant zero // bits of |x|. func (x *Int) TrailingZeroBits() uint { + panic("todo big.TrailingZeroBits") } -*/ // Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z. // If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. If m != 0, y < 0, @@ -417,7 +347,6 @@ func (z *Int) Exp(x, y, m *Int) *Int { return z } -/* // GCD sets z to the greatest common divisor of a and b and returns z. // If x or y are not nil, GCD sets their value such that z = a*x + b*y. // @@ -430,6 +359,7 @@ func (z *Int) Exp(x, y, m *Int) *Int { // // If a != 0 and b == 0, GCD sets z = |a|, x = sign(a) * 1, y = 0. func (z *Int) GCD(x, y, a, b *Int) *Int { + panic("todo big.GCD") } // Rand sets z to a pseudo-random number in [0, n) and returns z. @@ -437,6 +367,7 @@ func (z *Int) GCD(x, y, a, b *Int) *Int { // As this uses the math/rand package, it must not be used for // security-sensitive work. Use crypto/rand.Int instead. func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int { + panic("todo big.Rand") } // ModInverse sets z to the multiplicative inverse of g in the ring ℤ/nℤ @@ -444,11 +375,13 @@ func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int { // inverse in the ring ℤ/nℤ. In this case, z is unchanged and the return value // is nil. If n == 0, a division-by-zero run-time panic occurs. func (z *Int) ModInverse(g, n *Int) *Int { + panic("todo big.ModInverse") } // Jacobi returns the Jacobi symbol (x/y), either +1, -1, or 0. // The y argument must be an odd integer. func Jacobi(x, y *Int) int { + panic("todo big.Jacobi") } // ModSqrt sets z to a square root of x mod p if such a square root exists, and @@ -456,19 +389,29 @@ func Jacobi(x, y *Int) int { // ModSqrt leaves z unchanged and returns nil. This function panics if p is // not an odd integer, its behavior is undefined if p is odd but not prime. func (z *Int) ModSqrt(x, p *Int) *Int { + panic("todo big.ModSqrt") } // Lsh sets z = x << n and returns z. func (z *Int) Lsh(x *Int, n uint) *Int { + a := (*openssl.BIGNUM)(z) + b := (*openssl.BIGNUM)(x) + a.Lshift(b, c.Int(n)) + return z } // Rsh sets z = x >> n and returns z. func (z *Int) Rsh(x *Int, n uint) *Int { + a := (*openssl.BIGNUM)(z) + b := (*openssl.BIGNUM)(x) + a.Rshift(b, c.Int(n)) + return z } // Bit returns the value of the i'th bit of x. That is, it // returns (x>>i)&1. The bit index i must be >= 0. func (x *Int) Bit(i int) uint { + panic("todo big.Bit") } // SetBit sets z to x, with x's i'th bit set to b (0 or 1). @@ -476,32 +419,38 @@ func (x *Int) Bit(i int) uint { // if b is 0 SetBit sets z = x &^ (1 << i). If b is not 0 or 1, // SetBit will panic. func (z *Int) SetBit(x *Int, i int, b uint) *Int { + panic("todo big.SetBit") } // And sets z = x & y and returns z. func (z *Int) And(x, y *Int) *Int { + panic("todo big.And") } // AndNot sets z = x &^ y and returns z. func (z *Int) AndNot(x, y *Int) *Int { + panic("todo big.AndNot") } // Or sets z = x | y and returns z. func (z *Int) Or(x, y *Int) *Int { + panic("todo big.Or") } // Xor sets z = x ^ y and returns z. func (z *Int) Xor(x, y *Int) *Int { + panic("todo big.Xor") } // Not sets z = ^x and returns z. func (z *Int) Not(x *Int) *Int { + panic("todo big.Not") } // Sqrt sets z to ⌊√x⌋, the largest integer such that z² ≤ x, and returns z. // It panics if x is negative. func (z *Int) Sqrt(x *Int) *Int { + panic("todo big.Sqrt") } -*/ // ----------------------------------------------------------------------------- From c2bf05942eba9e771f55fd1e956f6999b129cebf Mon Sep 17 00:00:00 2001 From: tsingbx Date: Thu, 8 Aug 2024 13:34:04 +0800 Subject: [PATCH 4/4] add openssl BIGNUM support --- c/openssl/bn.go | 91 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/c/openssl/bn.go b/c/openssl/bn.go index 225dd324..37cf3452 100644 --- a/c/openssl/bn.go +++ b/c/openssl/bn.go @@ -202,23 +202,80 @@ func BNDec2bn(a **BIGNUM, str *c.Char) c.Int //go:linkname BNAsc2bn C.BN_asc2bn func BNAsc2bn(a **BIGNUM, str *c.Char) c.Int -/* -BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); -BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret); -int BN_bn2bin(const BIGNUM *a, unsigned char *to); -int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); -int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen); -BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); -BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); -int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen); -int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen); -BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret); -BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret); -int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen); -int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen); -BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); -int BN_bn2mpi(const BIGNUM *a, unsigned char *to); -*/ +// BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +// +//go:linkname BNBin2bn C.BN_bin2bn +func BNBin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM + +// BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +// +//go:linkname BNSignedBin2bn C.BN_signed_bin2bn +func BNSignedBin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM + +// int BN_bn2bin(const BIGNUM *a, unsigned char *to); +// +// llgo:link (*BIGNUM).Bn2bin C.BN_bn2bin +func (bn *BIGNUM) Bn2bin(to *byte) c.Int { return 0 } + +// int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); +// +// llgo:link (*BIGNUM).Bn2binpad C.BN_bn2binpad +func (bn *BIGNUM) Bn2binpad(to *byte, tolen c.Int) c.Int { return 0 } + +// int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen); +// +// llgo:link (*BIGNUM).SignedBn2bin C.BN_signed_bn2bin +func (bn *BIGNUM) SignedBn2bin(to *byte, tolen c.Int) c.Int { return 0 } + +// BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +// +//go:linkname BNLebin2bn C.BN_lebin2bn +func BNLebin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM + +// BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +// +//go:linkname BNSignedLebin2bn C.BN_signed_lebin2bn +func BNSignedLebin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM + +// int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen); +// +// llgo:link (*BIGNUM).Bn2lebinpad C.BN_bn2lebinpad +func (bn *BIGNUM) Bn2lebinpad(to *byte, tolen c.Int) c.Int { return 0 } + +// int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen); +// +// llgo:link (*BIGNUM).SignedBn2lebin C.BN_signed_bn2lebin +func (bn *BIGNUM) SignedBn2lebin(to *byte, tolen c.Int) c.Int { return 0 } + +// BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret); +// +//go:linkname BNNative2bn C.BN_native2bn +func BNNative2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM + +// BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret); +// +//go:linkname BNSignedNative2bn C.BN_signed_native2bn +func BNSignedNative2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM + +// int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen); +// +// llgo:link (*BIGNUM).Bn2nativepad C.BN_bn2nativepad +func (bn *BIGNUM) Bn2nativepad(to *byte, tolen c.Int) c.Int { return 0 } + +// int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen); +// +// llgo:link (*BIGNUM).SignedBn2native C.BN_signed_bn2native +func (bn *BIGNUM) SignedBn2native(to *byte, tolen c.Int) c.Int { return 0 } + +// BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +// +//go:linkname BNMpi2bn C.BN_mpi2bn +func BNMpi2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM + +// int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +// +// llgo:link (*BIGNUM).Bn2mpi C.BN_bn2mpi +func (bn *BIGNUM) Bn2mpi(to *byte) c.Int { return 0 } // int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); //