From 79d8b00b279a80819326d0564cd729a6aef9fb43 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 31 Jul 2024 22:34:13 +0800 Subject: [PATCH] c/openssl: bignum, rsa --- c/openssl/_demo/cbigintdemo/fib.go | 42 ++++ c/openssl/bn.go | 306 +++++++++++++++++++++++++++++ c/openssl/openssl.go | 12 ++ c/openssl/rsa.go | 60 ++++++ 4 files changed, 420 insertions(+) create mode 100644 c/openssl/_demo/cbigintdemo/fib.go create mode 100644 c/openssl/bn.go create mode 100644 c/openssl/rsa.go diff --git a/c/openssl/_demo/cbigintdemo/fib.go b/c/openssl/_demo/cbigintdemo/fib.go new file mode 100644 index 00000000..ce93c218 --- /dev/null +++ b/c/openssl/_demo/cbigintdemo/fib.go @@ -0,0 +1,42 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/openssl" +) + +func newInt(n openssl.BN_ULONG) *openssl.BIGNUM { + ret := openssl.BNNew() + ret.SetWord(n) + return ret +} + +func main() { + ctx := openssl.BN_CTXNew() + defer ctx.Free() + + // Initialize two big ints with the first two numbers in the sequence. + a := newInt(0) + b := newInt(1) + defer a.Free() + defer b.Free() + + // Initialize limit as 10^99, the smallest integer with 100 digits. + v10, v99 := newInt(10), newInt(99) + defer v10.Free() + defer v99.Free() + + limit := openssl.BNNew() + defer limit.Free() + + limit.Exp(v10, v99, ctx) + + // Loop while a is smaller than 1e100. + for a.Cmp(limit) < 0 { + // Compute the next Fibonacci number, storing it in a. + a.Add(a, b) + // Swap a and b so that b is the next number in the sequence. + a, b = b, a + } + c.Printf(c.Str("%s\n"), a.CStr()) // 100-digit Fibonacci number +} diff --git a/c/openssl/bn.go b/c/openssl/bn.go new file mode 100644 index 00000000..4b0d483d --- /dev/null +++ b/c/openssl/bn.go @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package openssl + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" +) + +type BN_ULONG = uint64 + +// ----------------------------------------------------------------------------- + +type BN_CTX struct { + Unused [0]byte +} + +// BN_CTX *BN_CTX_new(void); +// +//go:linkname BN_CTXNew C.BN_CTX_new +func BN_CTXNew() *BN_CTX + +// BN_CTX *BN_CTX_secure_new(void); +// +//go:linkname BN_CTXSecureNew C.BN_CTX_secure_new +func BN_CTXSecureNew() *BN_CTX + +// BN_CTX *BN_CTX_new_ex(OSSL_LIB_CTX *ctx); +// BN_CTX *BN_CTX_secure_new_ex(OSSL_LIB_CTX *ctx); + +// void BN_CTX_free(BN_CTX *c); +// +// llgo:link (*BN_CTX).Free C.BN_CTX_free +func (*BN_CTX) Free() {} + +// void BN_CTX_start(BN_CTX *ctx); +// BIGNUM *BN_CTX_get(BN_CTX *ctx); +// void BN_CTX_end(BN_CTX *ctx); + +// ----------------------------------------------------------------------------- + +type BIGNUM struct { + Unused [0]byte +} + +// BIGNUM *BN_new(void); +// +//go:linkname BNNew C.BN_new +func BNNew() *BIGNUM + +// BIGNUM *BN_secure_new(void); +// +//go:linkname BNSecureNew C.BN_secure_new +func BNSecureNew() *BIGNUM + +// void BN_free(BIGNUM *a); +// +// llgo:link (*BIGNUM).Free C.BN_free +func (*BIGNUM) Free() {} + +// void BN_clear_free(BIGNUM *a); +// +// llgo:link (*BIGNUM).ClearFree C.BN_clear_free +func (*BIGNUM) ClearFree() {} + +// void BN_clear(BIGNUM *a); +// +// llgo:link (*BIGNUM).Clear C.BN_clear +func (*BIGNUM) Clear() {} + +// BIGNUM *BN_dup(const BIGNUM *a); +// +// llgo:link (*BIGNUM).Dup C.BN_dup +func (*BIGNUM) Dup() *BIGNUM { return nil } + +// BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +// +// llgo:link (*BIGNUM).Copy C.BN_copy +func (*BIGNUM) Copy(b *BIGNUM) *BIGNUM { return nil } + +// void BN_swap(BIGNUM *a, BIGNUM *b); +// +// llgo:link (*BIGNUM).Swap C.BN_swap +func (*BIGNUM) Swap(b *BIGNUM) {} + +// int BN_set_word(BIGNUM *a, BN_ULONG w); +// +// llgo:link (*BIGNUM).SetWord C.BN_set_word +func (*BIGNUM) SetWord(w BN_ULONG) c.Int { return 0 } + +// BN_ULONG BN_get_word(const BIGNUM *a); +// +// llgo:link (*BIGNUM).GetWord C.BN_get_word +func (*BIGNUM) GetWord() BN_ULONG { return 0 } + +// BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +// +// llgo:link (*BIGNUM).ModWord C.BN_mod_word +func (*BIGNUM) ModWord(w BN_ULONG) BN_ULONG { return 0 } + +// BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +// +// llgo:link (*BIGNUM).DivWord C.BN_div_word +func (*BIGNUM) DivWord(w BN_ULONG) BN_ULONG { return 0 } + +// int BN_mul_word(BIGNUM *a, BN_ULONG w); +// +// llgo:link (*BIGNUM).MulWord C.BN_mul_word +func (*BIGNUM) MulWord(w BN_ULONG) c.Int { return 0 } + +// int BN_add_word(BIGNUM *a, BN_ULONG w); +// +// llgo:link (*BIGNUM).AddWord C.BN_add_word +func (*BIGNUM) AddWord(w BN_ULONG) c.Int { return 0 } + +// int BN_sub_word(BIGNUM *a, BN_ULONG w); +// +// llgo:link (*BIGNUM).SubWord C.BN_sub_word +func (*BIGNUM) SubWord(w BN_ULONG) c.Int { return 0 } + +// char *BN_bn2hex(const BIGNUM *a); +// +// llgo:link (*BIGNUM).Bn2hex C.BN_bn2hex +func (*BIGNUM) Bn2hex() *c.Char { return nil } + +// char *BN_bn2dec(const BIGNUM *a); +// +// llgo:link (*BIGNUM).Bn2dec C.BN_bn2dec +func (*BIGNUM) Bn2dec() *c.Char { return nil } + +// llgo:link (*BIGNUM).CStr C.BN_bn2dec +func (*BIGNUM) CStr() *c.Char { return nil } + +// int BN_hex2bn(BIGNUM **a, const char *str); +// +//go:linkname BNHex2bn C.BN_hex2bn +func BNHex2bn(a **BIGNUM, str *c.Char) c.Int + +// int BN_dec2bn(BIGNUM **a, const char *str); +// +//go:linkname BNDec2bn C.BN_dec2bn +func BNDec2bn(a **BIGNUM, str *c.Char) c.Int + +// int BN_asc2bn(BIGNUM **a, const char *str); +// +//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); +*/ + +// int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +// +// llgo:link (*BIGNUM).Sub C.BN_sub +func (*BIGNUM) Sub(a, b *BIGNUM) c.Int { return 0 } + +// int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +// +// llgo:link (*BIGNUM).Add C.BN_add +func (*BIGNUM) Add(a, b *BIGNUM) c.Int { return 0 } + +// int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +// +// llgo:link (*BIGNUM).Usub C.BN_usub +func (*BIGNUM) Usub(a, b *BIGNUM) c.Int { return 0 } + +// int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +// +// llgo:link (*BIGNUM).Uadd C.BN_uadd +func (*BIGNUM) Uadd(a, b *BIGNUM) c.Int { return 0 } + +// int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +// +// llgo:link (*BIGNUM).Mul C.BN_mul +func (*BIGNUM) Mul(r, a, b *BIGNUM, ctx *BN_CTX) c.Int { return 0 } + +// int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +// +// llgo:link (*BIGNUM).Sqr C.BN_sqr +func (*BIGNUM) Sqr(r, a *BIGNUM, ctx *BN_CTX) c.Int { return 0 } + +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +// void BN_set_negative(BIGNUM *b, int n); +// +// llgo:link (*BIGNUM).SetNegative C.BN_set_negative +func (*BIGNUM) SetNegative(n c.Int) {} + +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param b pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +// int BN_is_negative(const BIGNUM *b); +// +// llgo:link (*BIGNUM).IsNegative C.BN_is_negative +func (*BIGNUM) IsNegative() c.Int { return 0 } + +// int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +// +// llgo:link (*BIGNUM).Div C.BN_div +func (*BIGNUM) Div(rem, m, d *BIGNUM, ctx *BN_CTX) c.Int { return 0 } + +// int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +// +// llgo:link (*BIGNUM).Nnmod C.BN_nnmod +func (*BIGNUM) Nnmod(r, m, d *BIGNUM, ctx *BN_CTX) c.Int { return 0 } + +// int BN_cmp(const BIGNUM *a, const BIGNUM *b); +// +// llgo:link (*BIGNUM).Cmp C.BN_cmp +func (*BIGNUM) Cmp(b *BIGNUM) c.Int { return 0 } + +// int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +// +// llgo:link (*BIGNUM).Ucmp C.BN_ucmp +func (*BIGNUM) Ucmp(b *BIGNUM) c.Int { return 0 } + +// int BN_is_bit_set(const BIGNUM *a, int n); +// +// llgo:link (*BIGNUM).IsBitSet C.BN_is_bit_set +func (*BIGNUM) IsBitSet(n c.Int) c.Int { return 0 } + +// int BN_set_bit(BIGNUM *a, int n); +// +// llgo:link (*BIGNUM).SetBit C.BN_set_bit +func (*BIGNUM) SetBit(n c.Int) c.Int { return 0 } + +// int BN_clear_bit(BIGNUM *a, int n); +// +// llgo:link (*BIGNUM).ClearBit C.BN_clear_bit +func (*BIGNUM) ClearBit(n c.Int) c.Int { return 0 } + +// int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +// +// llgo:link (*BIGNUM).Lshift C.BN_lshift +func (*BIGNUM) Lshift(a *BIGNUM, n c.Int) c.Int { return 0 } + +// int BN_lshift1(BIGNUM *r, const BIGNUM *a); +// +// llgo:link (*BIGNUM).Lshift1 C.BN_lshift1 +func (*BIGNUM) Lshift1(a *BIGNUM) c.Int { return 0 } + +// int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +// +// llgo:link (*BIGNUM).Rshift C.BN_rshift +func (*BIGNUM) Rshift(a *BIGNUM, n c.Int) c.Int { return 0 } + +// int BN_rshift1(BIGNUM *r, const BIGNUM *a); +// +// llgo:link (*BIGNUM).Rshift1 C.BN_rshift1 +func (*BIGNUM) Rshift1(a *BIGNUM) c.Int { return 0 } + +// int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +// +// llgo:link (*BIGNUM).Exp C.BN_exp +func (*BIGNUM) Exp(a, p *BIGNUM, ctx *BN_CTX) c.Int { return 0 } + +// int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +// +// llgo:link (*BIGNUM).Gcd C.BN_gcd +func (*BIGNUM) Gcd(a, b *BIGNUM, ctx *BN_CTX) c.Int { return 0 } + +// int BN_are_coprime(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +// +// llgo:link (*BIGNUM).AreCoprime C.BN_are_coprime +func (*BIGNUM) AreCoprime(b *BIGNUM, ctx *BN_CTX) c.Int { return 0 } + +// ----------------------------------------------------------------------------- + +type BN_GENCB struct { + Unused [0]byte +} + +// ----------------------------------------------------------------------------- diff --git a/c/openssl/openssl.go b/c/openssl/openssl.go index 491f61fe..0762808a 100644 --- a/c/openssl/openssl.go +++ b/c/openssl/openssl.go @@ -16,10 +16,22 @@ package openssl +import ( + "unsafe" + + "github.com/goplus/llgo/c" +) + // ----------------------------------------------------------------------------- const ( LLGoPackage = "link: $(pkg-config --libs openssl); -lssl -lcrypto" ) +//go:linkname Free C.OPENSSL_free +func Free(ptr unsafe.Pointer) + +//go:linkname FreeCStr C.OPENSSL_free +func FreeCStr(ptr *c.Char) + // ----------------------------------------------------------------------------- diff --git a/c/openssl/rsa.go b/c/openssl/rsa.go new file mode 100644 index 00000000..378ba424 --- /dev/null +++ b/c/openssl/rsa.go @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package openssl + +import ( + "unsafe" + + "github.com/goplus/llgo/c" +) + +// ----------------------------------------------------------------------------- + +type RSA struct { + Unused [0]byte +} + +// OSSL_DEPRECATEDIN_3_0 RSA *RSA_new(void); +// +//go:linkname RSANew C.RSA_new +func RSANew() *RSA + +// OSSL_DEPRECATEDIN_3_0 RSA *RSA_new_method(ENGINE *engine); + +// OSSL_DEPRECATEDIN_3_0 int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +// +// llgo:link (*RSA).GenerateKeyEx C.RSA_generate_key_ex +func (*RSA) GenerateKeyEx(bits c.Int, e *BIGNUM, cb *BN_GENCB) c.Int { return 0 } + +// OSSL_DEPRECATEDIN_3_0 int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb); +// +// llgo:link (*RSA).GenerateMultiPrimeKey C.RSA_generate_multi_prime_key +func (*RSA) GenerateMultiPrimeKey(bits, primes c.Int, e *BIGNUM, cb *BN_GENCB) c.Int { return 0 } + +// OSSL_DEPRECATEDIN_3_0 int RSA_sign( +// int type, const unsigned char *m, unsigned int m_length, +// unsigned char *sigret, unsigned int *siglen, RSA *rsa); +// +//go:linkname RSASign C.RSA_sign +func RSASign(typ c.Int, msg unsafe.Pointer, mlen c.Uint, sigret *byte, siglen *c.Uint, rsa *RSA) c.Int + +// OSSL_DEPRECATEDIN_3_0 int RSA_verify(int type, const unsigned char *m, +// unsigned int m_length, +// const unsigned char *sigbuf, +// unsigned int siglen, RSA *rsa); + +// -----------------------------------------------------------------------------