ring icon indicating copy to clipboard operation
ring copied to clipboard

Build for wasm

Open Kayryu opened this issue 3 years ago • 3 comments

My goal is to make the Ring library usable in WASM. In a simple example, project DEMO relies on Ring and builds project DEMO with wasm-pack, but cannot be used directly in JS. I then used wasm2wat to convert the compiled files and found the following functions is missing.

  (import "env" "GFp_nistz256_mul_mont" (func (;0;) (type 3)))
  (import "env" "GFp_nistz256_add" (func (;1;) (type 3)))
  (import "env" "GFp_nistz256_point_double" (func (;3;) (type 2)))
  (import "env" "GFp_nistz256_neg" (func (;4;) (type 2)))
  (import "env" "GFp_nistz256_point_add_affine" (func (;5;) (type 3)))
  (import "env" "GFp_bn_mul_mont" (func (;6;) (type 13)))

I discovered that the GFp_bn_mul_mont function was written in Perl, But I'm not sure perl is involved.

Kayryu avatar Apr 12 '22 03:04 Kayryu

I'm successfully using ring within a JavaScript-enabled WASM runtime (on the browser, specifically).

You might consider trying something like this:

[dependencies.ring]
version = "0.17.0-alpha.11"
features = ["std", "wasm32_c"]

maxcountryman avatar May 06 '22 14:05 maxcountryman

Yes, if I only use ECDSA-related functions of ring, it can compile and run on the browser, but once I use Ed25519 related functions, I will get an error. The code is as follows:

use ring::{
         rand,
         signature::{self, KeyPair},
     };
use hex::FromHex;
let rng = rand::SystemRandom::new();
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap();
let key_pair = signature::Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref()).unwrap();
const MESSAGE: &[u8] = b"hello, world";
let sig = key_pair.sign(MESSAGE);

Kayryu avatar May 07 '22 02:05 Kayryu

i have successful build my application with ring from last main git for wasm on macos we need llvm with wasm target and clang brew install llvm

LLVM_PATH=/opt/homebrew/opt/llvm/

RUSTC_WRAPPER="" \
\
CC_wasm32_unknown_unknown=${LLVM_PATH:?}/bin/clang \
CXX_wasm32_unknown_unknown=${LLVM_PATH:?}/bin/clang++ \
AS_wasm32_unknown_unknown=${LLVM_PATH:?}/bin/llvm-as \
AR_wasm32_unknown_unknown=${LLVM_PATH:?}/bin/llvm-ar \
STRIP_wasm32_unknown_unknown=${LLVM_PATH:?}/bin/llvm-strip \
\
wasm-pack build \
    --out-dir "${output_path:?}" \
    --target web \
    --release

need to comment #[cfg(not(target_arch = "wasm32"))] in ring code for 25519 DH https://github.com/briansmith/ring/blob/0f3bf0031a8dbba741b26f1f02ebde6b7db4a3d6/src/lib.rs#L82 https://github.com/briansmith/ring/blob/0f3bf0031a8dbba741b26f1f02ebde6b7db4a3d6/src/ec.rs#L39 https://github.com/briansmith/ring/blob/0f3bf0031a8dbba741b26f1f02ebde6b7db4a3d6/src/ec/curve25519.rs#L19 https://github.com/briansmith/ring/blob/0f3bf0031a8dbba741b26f1f02ebde6b7db4a3d6/src/ec/suite_b.rs#L232

chertov avatar Jun 02 '22 18:06 chertov

Has anyone here encountered or had to work around issues with ring expecting exports that don't exist, like LIMBS_are_zero?

https://github.com/briansmith/ring/issues/1453#issuecomment-1295637393

I can successfully build but then my environment complains about things like Module imports function 'LIMBS_are_zero' from 'env' that is not exported by the runtime.

Do I need to try to build things differently to fix that?

I tried the env vars @chertov suggested that failed for me:

(Click to expand)
error: failed to run custom build command for `ring v0.17.0-not-released-yet (/Users/py/projects/briansmith/ring/codebase-labs/wasm32-unknown-unknown)`
Caused by:
  process didn't exit successfully: `/private/tmp/nix-build-rust-workspace-deps-unknown.drv-1/dummy-src/target/release/build/ring-7aedbc6fa20be512/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-env-changed=RING_PREGENERATE_ASM
  cargo:rustc-env=RING_CORE_PREFIX=ring_core_0_17_0_not_released_yet_
  OPT_LEVEL = Some("z")
  TARGET = Some("wasm32-unknown-unknown")
  HOST = Some("aarch64-apple-darwin")
  CC_wasm32-unknown-unknown = None
  CC_wasm32_unknown_unknown = Some("clang")
  CFLAGS_wasm32-unknown-unknown = None
  CFLAGS_wasm32_unknown_unknown = None
  TARGET_CFLAGS = None
  CFLAGS = None
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("false")
  --- stderr
  running "clang" "-Oz" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=wasm32-unknown-unknown" "-I" "include" "-I" "/private/tmp/nix-build-rust-workspace-deps-unknown.drv-1/dummy-src/target/wasm32-unknown-unknown/release/build/ring-e9d9bfabc386e4cd/out" "-Wall" "-Wextra" "-std=c1x" "-Wbad-function-cast" "-Wnested-externs" "-Wstrict-prototypes" "-pedantic" "-pedantic-errors" "-Wall" "-Wextra" "-Wcast-align" "-Wcast-qual" "-Wconversion" "-Wenum-compare" "-Wfloat-equal" "-Wformat=2" "-Winline" "-Winvalid-pch" "-Wmissing-field-initializers" "-Wmissing-include-dirs" "-Wredundant-decls" "-Wshadow" "-Wsign-compare" "-Wsign-conversion" "-Wundef" "-Wuninitialized" "-Wwrite-strings" "-fno-strict-aliasing" "-fvisibility=hidden" "-g3" "-nostdlibinc" "-DNDEBUG" "-DRING_CORE_NOSTDLIBINC=1" "-Werror" "-c" "-o/private/tmp/nix-build-rust-workspace-deps-unknown.drv-1/dummy-src/target/wasm32-unknown-unknown/release/build/ring-e9d9bfabc386e4cd/out/curve25519.o" "crypto/curve25519/curve25519.c"
  clang-11: error: argument unused during compilation: '-mmacos-version-min=11.0' [-Werror,-Wunused-command-line-argument]
  clang-11: error: argument unused during compilation: '-nostdlibinc' [-Werror,-Wunused-command-line-argument]
  clang-11: error: argument unused during compilation: '-arch arm64' [-Werror,-Wunused-command-line-argument]
  thread 'main' panicked at 'execution failed', /Users/py/projects/briansmith/ring/codebase-labs/wasm32-unknown-unknown/build.rs:707:9
  stack backtrace:
     0: rust_begin_unwind
               at /rustc/e0944922007e1bb4fe59809293acf4364410cccc/library/std/src/panicking.rs:584:5
     1: core::panicking::panic_fmt
               at /rustc/e0944922007e1bb4fe59809293acf4364410cccc/library/core/src/panicking.rs:142:14
     2: build_script_build::run_command
     3: build_script_build::compile
     4: build_script_build::build_library::{{closure}}
     5: core::iter::adapters::map::map_fold::{{closure}}
     6: core::iter::traits::iterator::Iterator::fold
     7: <:iter::adapters::chain::chain> as core::iter::traits::iterator::Iterator>::fold
     8: <:iter::adapters::map::map> as core::iter::traits::iterator::Iterator>::fold
     9: core::iter::traits::iterator::Iterator::for_each
    10: <:vec::vec> as alloc::vec::spec_extend::SpecExtend>::spec_extend
    11: <:vec::vec> as alloc::vec::spec_from_iter_nested::SpecFromIterNested>::from_iter
    12: <:vec::vec> as alloc::vec::spec_from_iter::SpecFromIter>::from_iter
    13: <:vec::vec> as core::iter::traits::collect::FromIterator>::from_iter
    14: core::iter::traits::iterator::Iterator::collect
    15: build_script_build::build_library
    16: build_script_build::build_c_code::{{closure}}
    17: <:slice::iter::iter> as core::iter::traits::iterator::Iterator>::for_each
    18: build_script_build::build_c_code
    19: build_script_build::ring_build_rs_main
    20: build_script_build::main
    21: core::ops::function::FnOnce::call_once

paulyoung avatar Oct 30 '22 23:10 paulyoung

@chertov which version of llvm are you using?

paulyoung avatar Oct 30 '22 23:10 paulyoung

I tried the env vars @chertov suggested that failed for me

Based on the errors there I set CFLAGS_wasm32_unknown_unknown = "-Qunused-arguments"; and then arrived at:

error: unknown target CPU 'apple-a13'
note: valid target CPU values are: mvp, bleeding-edge, generic

I've gotten stuck on this before and never gotten past it.

Instead of all the env vars listed I can set TARGET_CC to build otherwise, but then I'm back to the problem about LIMBS_are_zero.

paulyoung avatar Oct 30 '22 23:10 paulyoung

@paulyoung hi, my buildscript and clang version

function build_wasm() {
    LLVM_PATH=/opt/homebrew/opt/llvm/

    RUSTFLAGS=--cfg=web_sys_unstable_apis \
    RUSTC_WRAPPER="" \
    \
    CC_wasm32_unknown_unknown=${LLVM_PATH}/bin/clang \
    CXX_wasm32_unknown_unknown=${LLVM_PATH}/bin/clang++ \
    AS_wasm32_unknown_unknown=${LLVM_PATH}/bin/llvm-as \
    AR_wasm32_unknown_unknown=${LLVM_PATH}/bin/llvm-ar \
    STRIP_wasm32_unknown_unknown=${LLVM_PATH}/bin/llvm-strip \
    \
    rustup run stable wasm-pack build \
        --out-dir "${output_path:?}" \
        --target web \
        --release
}
/opt/homebrew/opt/llvm/bin/clang --version
Homebrew clang version 14.0.6
Target: arm64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /opt/homebrew/opt/llvm/bin

chertov avatar Oct 31 '22 03:10 chertov

@chertov thanks!

RUSTFLAGS seems to be the only difference from https://github.com/briansmith/ring/issues/1483#issuecomment-1145159978. I’ll give this a try in the morning.

paulyoung avatar Oct 31 '22 04:10 paulyoung

…although that seems unrelated to my issue.

paulyoung avatar Oct 31 '22 05:10 paulyoung

I'm closing this as a duplicate of #918, which is about the same thing: Not all of the ring features are implemented when targeting wasm32 targets.

briansmith avatar Nov 09 '22 20:11 briansmith