Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust bindings #287

Merged
merged 7 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build]
# https://doc.rust-lang.org/rustc/linker-plugin-lto.html
rustflags="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld"
20 changes: 12 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,16 +236,18 @@ jobs:
shell: bash
run: |
cd constantine
nimble bindings --verbose
nimble test_bindings --verbose
nimble make_lib --verbose
nimble make_headers --verbose
nimble test_lib --verbose
nimble test_parallel --verbose
- name: Run Constantine tests (UNIX no Assembly)
if: runner.os != 'Windows' && matrix.target.BACKEND == 'NO_ASM'
shell: bash
run: |
cd constantine
CTT_ASM=0 nimble bindings --verbose
nimble test_bindings --verbose
CTT_ASM=0 nimble make_lib --verbose
nimble make_headers --verbose
nimble test_lib --verbose
CTT_ASM=0 nimble test_parallel --verbose
- name: Run Constantine tests (Windows with Assembly)
# So "test_bindings" uses C and can find GMP
Expand All @@ -254,8 +256,9 @@ jobs:
shell: msys2 {0}
run: |
cd constantine
nimble bindings --verbose
nimble test_bindings --verbose
nimble make_lib --verbose
nimble make_headers --verbose
nimble test_lib --verbose
nimble test_parallel_no_gmp --verbose
- name: Run Constantine tests (Windows no Assembly)
# So "test_bindings" uses C and can find GMP
Expand All @@ -264,6 +267,7 @@ jobs:
shell: msys2 {0}
run: |
cd constantine
CTT_ASM=0 nimble bindings --verbose
nimble test_bindings --verbose
CTT_ASM=0 nimble make_lib --verbose
nimble make_headers --verbose
nimble test_lib --verbose
CTT_ASM=0 nimble test_parallel_no_gmp --verbose
40 changes: 35 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,47 @@
nimcache/

# Executables shall be put in an ignored build/ directory
# Ignore dynamic, static libs and libtool archive files
build/
*.so
*.so.*
*.dylib
*.a
*.la
*.exe
*.dll
*.exe
*.out

# Nim
# -----------------------------------------------------------------------------------------
nimcache/

# Rust
# -----------------------------------------------------------------------------------------

# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# Sage
# -----------------------------------------------------------------------------------------
*.sage.py

# Tests
test_*.txt
# Swap or debug
# -----------------------------------------------------------------------------------------
*.swp
*~

# Perf artifacts
# -----------------------------------------------------------------------------------------
perf.data
perf.data.old
23 changes: 23 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[workspace]
resolver = "2"
members = [
"constantine-rust/constantine-sys",
"constantine-rust/ctt-curve-bls12-381",
"constantine-rust/ctt-curve-bn254-snarks",
"constantine-rust/ctt-curve-pasta",
"constantine-rust/ctt-proto-ethereum-bls-signatures",
]

# The Nim static library is compiled with ThinLTO, always enable it

[profile.dev]
lto = "thin"

[profile.test]
lto = "thin"

[profile.release]
lto = "thin"

[profile.bench]
lto = "thin"
File renamed without changes.
File renamed without changes.
65 changes: 12 additions & 53 deletions bindings_generators/gen_header.nim → bindings/c_typedefs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ proc genHeaderLicense*(): string =
*/
"""

proc genHeader*(name, body: string): string =
proc genHeaderGuardAndInclude*(name, body: string): string =
&"""
#ifndef __CTT_H_{name}__
#define __CTT_H_{name}__

#include "constantine/core/datatypes.h"

{body}

#endif
Expand Down Expand Up @@ -70,9 +72,9 @@ typedef __UINT64_TYPE__ uint64_t;
#endif

#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901
# define bool _Bool
# define ctt_bool _Bool
#else
# define bool unsigned char
# define ctt_bool unsigned char
#endif
"""

Expand All @@ -85,12 +87,12 @@ typedef uint8_t byte;

proc genWordsRequired*(): string =
"""
#define WordBitWidth (sizeof(secret_word)*8)
#define words_required(bits) ((bits+WordBitWidth-1)/WordBitWidth)
#define CTT_WORD_BITWIDTH (sizeof(secret_word)*8)
#define CTT_WORDS_REQUIRED(bits) ((bits+WordBitWidth-1)/WordBitWidth)
"""

proc genField*(name: string, bits: int): string =
&"typedef struct {{ secret_word limbs[words_required({bits})]; }} {name};"
&"typedef struct {{ secret_word limbs[CTT_WORDS_REQUIRED({bits})]; }} {name};"

proc genExtField*(name: string, degree: int, basename: string): string =
&"typedef struct {{ {basename} c[{degree}]; }} {name};"
Expand Down Expand Up @@ -121,20 +123,20 @@ void ctt_{libName}_init_NimMain(void);"""
# -------------------------------------------

let TypeMap {.compileTime.} = newStringTable({
"bool": "bool",
"bool": "ctt_bool ",
"SecretBool": "secret_bool",
"SecretWord": "secret_word"
})

proc toCrettype(node: NimNode): string =
proc toCrettype*(node: NimNode): string =
node.expectKind({nnkEmpty, nnkSym})
if node.kind == nnkEmpty:
# align iwth secret_bool and secret_word
"void "
else:
TypeMap[$node]

proc toCtrivialParam(name: string, typ: NimNode): string =
proc toCtrivialParam*(name: string, typ: NimNode): string =
typ.expectKind({nnkVarTy, nnkSym})

let isVar = typ.kind == nnkVarTy
Expand All @@ -151,7 +153,7 @@ proc toCtrivialParam(name: string, typ: NimNode): string =
# Pass-by-reference
constify & sTyp & "* " & name

proc toCparam(name: string, typ: NimNode): string =
proc toCparam*(name: string, typ: NimNode): string =
typ.expectKind({nnkVarTy, nnkCall, nnkSym})

if typ.kind == nnkCall:
Expand All @@ -174,46 +176,3 @@ proc toCparam(name: string, typ: NimNode): string =
sTyp & " " & name & "[], ptrdiff_t " & name & "_len"
else:
toCtrivialParam(name, typ)

macro collectBindings*(cBindingsStr: untyped, body: typed): untyped =
## Collect function definitions from a generator template

body.expectKind(nnkStmtList)

var cBindings: string

for generator in body:
generator.expectKind(nnkStmtList)
for fnDef in generator:
if fnDef.kind notin {nnkProcDef, nnkFuncDef}:
continue

cBindings &= "\n"
# rettype name(pType0* pName0, pType1* pName1, ...);
cBindings &= fnDef.params[0].toCrettype()
cBindings &= ' '
cBindings &= $fnDef.name
cBindings &= '('
for i in 1 ..< fnDef.params.len:
if i != 1: cBindings &= ", "

let paramDef = fnDef.params[i]
paramDef.expectKind(nnkIdentDefs)
let pType = paramDef[^2]
# No default value
paramDef[^1].expectKind(nnkEmpty)

for j in 0 ..< paramDef.len - 2:
if j != 0: cBindings &= ", "
var name = $paramDef[j]
cBindings &= toCparam(name.split('`')[0], pType)

if fnDef.params[0].eqIdent"bool":
cBindings &= ") __attribute__((warn_unused_result));"
else:
cBindings &= ");"

if defined(CTT_GENERATE_HEADERS):
result = newConstStmt(cBindingsStr, newLit cBindings)
else:
result = body
21 changes: 21 additions & 0 deletions bindings/lib_constantine.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Constantine
# Copyright (c) 2018-2019 Status Research & Development GmbH
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.

# ############################################################
#
# Constantine library
#
# ############################################################

{.push warning[UnusedImport]: off.}

import
./lib_hashes,
./lib_curves,
# Protocols
../constantine/ethereum_bls_signatures
Loading
Loading