Skip to content

Commit

Permalink
Initial js wrapper
Browse files Browse the repository at this point in the history
Fixing memory allocation issues
ignore workspace
Update README.md
  • Loading branch information
jleni committed Sep 25, 2017
1 parent cd74e8b commit 4680eb2
Show file tree
Hide file tree
Showing 21 changed files with 340 additions and 137 deletions.
10 changes: 8 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ benchmark/speedup_sign\.png
benchmark/speedup_create\.png
benchmark/speedup_verify\.png

\.idea/workspace\.xml

googletest-src/
googletest-download/
googletest-build/
Expand All @@ -41,3 +39,11 @@ gmock_main\.pc
gmock\.pc
gtest\.pc
qrllib_test

cmake-build-onlylib/
build/
\.idea/workspace\.xml
\.coverage
coverage\.xml
.eggs/
pyqrllib.egg-info/
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ python:
- '3.4'
env:
matrix:
- CC_VER="4" PLATFORM='xenial'
- CC_VER="5" PLATFORM='xenial'
cache:
timeout: 600
Expand Down
79 changes: 56 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ set(CMAKE_VERBOSE_MAKEFILE ON)
set(BUILD_TESTS OFF CACHE BOOL "Enables tests")
set(BUILD_GO OFF CACHE BOOL "Enables go wrapper")
set(BUILD_PYTHON ON CACHE BOOL "Enables python wrapper")
set(BUILD_WEBASSEMBLY OFF CACHE BOOL "Enables emscripten build")
set(BUILD_PYTHON_LOCALDEPLOY ON CACHE BOOL "Deploys python locally")

message(STATUS "GOLANG WRAPPER" ${BUILD_GO})
message(STATUS "PYTHON WRAPPER" ${BUILD_PYTHON})
message(STATUS "GOLANG WRAPPER " ${BUILD_GO})
message(STATUS "PYTHON WRAPPER " ${BUILD_PYTHON})
message(STATUS "WEBASSEMBLY " ${BUILD_WEBASSEMBLY})

find_package(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
unset(SWIG_LANG_TYPE)
if (BUILD_PYTHON OR BUILD_GO)
find_package(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
unset(SWIG_LANG_TYPE)
endif()

include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/src/api
Expand All @@ -30,8 +34,14 @@ include_directories(

set(SWIG_INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/src/api/api.i)

set(JS_INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/src/jswrapper/jswrapper.cpp
)

file(GLOB_RECURSE LIB_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib/*.cpp")

file(GLOB_RECURSE LIBTEST_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/src/tests/*.cpp")

Expand Down Expand Up @@ -119,15 +129,19 @@ endif()

## SWIG + API - Python related stuff
if (BUILD_PYTHON)
message(STATUS ¨Python wrapper enabled¨)
message(STATUS "Python wrapper enabled")
set(language python)
find_package(PythonLibs 3.4 REQUIRED)
include_directories(${PYTHON_INCLUDE_PATH})

set(SWIG_LANG_LIBRARIES ${PYTHON_LIBRARIES})
set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_SOURCE_DIR}/pyqrllib)
set(CMAKE_SWIG_OUTDIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pyqrllib)
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pyqrllib)
set_source_files_properties(${SWIG_INTERFACE} PROPERTIES CPLUSPLUS ON)
set_property(SOURCE ${SWIG_INTERFACE} PROPERTY SWIG_FLAGS "-includeall" "-ignoremissing")

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pyqrllib)

# Intentionally use a deprecated version to provide support for the raspberry pi
SWIG_ADD_MODULE( pyqrllib
${language}
Expand All @@ -151,25 +165,35 @@ if (BUILD_PYTHON)
SWIG_LINK_LIBRARIES(pyqrllib ${SWIG_LANG_LIBRARIES})
#add_dependencies(${SWIG_MODULE_pyqrllib_REAL_NAME} prepareXMSSParams)

if (BUILD_PYTHON_LOCALDEPLOY)
add_custom_command(TARGET ${SWIG_MODULE_pyqrllib_REAL_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan $<TARGET_FILE:${SWIG_MODULE_pyqrllib_REAL_NAME}>
COMMENT "Moving SWIG files to output dir"
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${SWIG_MODULE_pyqrllib_REAL_NAME}> ${CMAKE_CURRENT_SOURCE_DIR}/pyqrllib
)
# Get python packages destination
#execute_process(COMMAND python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
# OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
# Use CPack to create wheel packages
#install(TARGETS _target DESTINATION ${PYTHON_SITE_PACKAGES})
#install(FILES ${CMAKE_BINARY_DIR}/src/target.py DESTINATION ${PYTHON_SITE_PACKAGES})
endif()
get_cmake_property(_variableNames VARIABLES)
foreach (_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()

add_custom_command(TARGET ${SWIG_MODULE_pyqrllib_REAL_NAME}
POST_BUILD
COMMENT "Moving SWIG files to output dir"
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${SWIG_MODULE_pyqrllib_REAL_NAME}> ${CMAKE_CURRENT_SOURCE_DIR}/pyqrllib/$<TARGET_LINKER_FILE_NAME:${SWIG_MODULE_pyqrllib_REAL_NAME}>
)

add_custom_command(TARGET ${SWIG_MODULE_pyqrllib_REAL_NAME}
POST_BUILD
COMMENT ${swig_extra_generated_files}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${swig_extra_generated_files} ${CMAKE_CURRENT_SOURCE_DIR}/pyqrllib/pyqrllib.py
)


# Get python packages destination
#execute_process(COMMAND python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
# OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
# Use CPack to create wheel packages
#install(TARGETS _target DESTINATION ${PYTHON_SITE_PACKAGES})
#install(FILES ${CMAKE_BINARY_DIR}/src/target.py DESTINATION ${PYTHON_SITE_PACKAGES})
endif ()

# SWIG + API - Golang related stuff
if (BUILD_GO)
message(STATUS ¨golang wrapper enabled¨)
message(STATUS "golang wrapper enabled")
set(language go)
#find_package(go 1.5 REQUIRED)
#include_directories(${PYTHON_INCLUDE_PATH})
Expand All @@ -186,7 +210,6 @@ if (BUILD_GO)
${LIBXMSSALT_SRC}
)


# SWIG_ADD_LIBRARY(goqrllib
# ${language}
# ${SWIG_LANG_TYPE}
Expand All @@ -205,3 +228,13 @@ if (BUILD_GO)
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${SWIG_MODULE_goqrllib_REAL_NAME}> ${CMAKE_CURRENT_SOURCE_DIR}/goqrllib
)
endif ()

if (BUILD_WEBASSEMBLY)
message(STATUS "webassembly enabled")
add_library(jsqrl SHARED
${JS_INTERFACE}
${LIB_SRC}
${LIBXMSSALT_SRC}
)

endif ()
34 changes: 13 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,19 @@ This library currently exposes the following functionality:

**Platform support**

| | Linux | OSX<br>10.12 | Windows<br>10 | Raspbian<br>? | Chrome<br>(Webassembly) |
|-----------|:------------:|:-----------:|:--------:|:--------:|:-----------:|
|Python 2 | :x: | :x: | - | - | - |
|Python 3 | :white_check_mark: | :white_check_mark: | :seedling: | :question: | :question: |
|Golang | wrapper<br>generation only | - | - | - | - |
|Java | - | - | - | - | - |
|Javascript | - | - | - | - | - |
| | Linux | OSX<br>10.12 | Windows<br>10 | Raspbian<br>? |
|-----------|:------------:|:-----------:|:--------:|:--------:|
|Python 2 | :x: | :x: | :x: | :x: |
|Python 3 | :white_check_mark: | :white_check_mark: | :seedling: | :white_check_mark: |
|Webassembly (JS) | :white_check_mark: | :seedling: | :white_check_mark: | :white_check_mark: |
|Golang | wrapper<br>generation only | - | - | - |
|Java | - | - | - | - |

## Installing

*TODO: Work in progress.*

#### Ubuntu
```
sudo apt -y install swig3.0 python3-dev build-essential pkg-config
sudo apt -y install swig3.0 python3-dev build-essential cmake pkg-config
pip3 install pyqrllib
````
Expand All @@ -56,17 +54,11 @@ TBD

#### Raspbian

A bug in one of the dependencies is affecting us. A workaround is provided for integration testing. Use at your own risk.

Download the following script and execute as sudo. It will take a while to compile cmake.


> **These are the original instructions but wont work until a bug in cmake is solved**
>```
>sudo apt -y install swig3.0 python3-dev build-essential cmake ninja
>sudo pip3 install -U setuptools scikit-build
>sudo pip3 install pyqrllib
>```
```
sudo apt -y install swig3.0 python3-dev build-essential cmake ninja-build
sudo pip3 install -U setuptools
sudo pip3 install -U pyqrllib
```

#### Miscellaneous

Expand Down
8 changes: 8 additions & 0 deletions build_webassembly.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
mkdir -p ./build
cd ./build
emconfigure cmake -DBUILD_WEBASSEMBLY=ON -DBUILD_PYTHON=OFF ..
emmake make
emcc --bind libjsqrl.so -O3 -o libjsqrl.js
cp ../src/tests_js/test.js .
node test.js
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Add your requirements here like:
scikit-build

22 changes: 2 additions & 20 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,12 @@ classifier =
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5

[entry_points]
# Add here console scripts like:
# console_scripts =
# script_name = pyqrllib.module:function
# For example:
# console_scripts =
# fibonacci = pyqrllib.skeleton:run
# as well as other entry_points.


[files]
# Add here 'data_files', 'packages' or 'namespace_packages'.
# Additional data files are defined as key value pairs of target directory
# and source location from the root of the repository:
packages =
pyqrllib
packages = pyqrllib
data_files =
pyqrllib = pyqrllib/_pyqrllib.so pyqrllib/pyqrllib.py

[extras]
# Add here additional requirements for extra features, like:
# PDF =
# ReportLab>=1.2
# RXP

[test]
# py.test options when running `python setup.py test`
Expand All @@ -51,7 +33,7 @@ addopts = src/tests_python
# in order to write a coverage file that can be read by Jenkins.
addopts =
--doctest-modules -s
--cov qrl --cov-report term-missing --cov-report xml
--cov pyqrllib --cov-report term-missing --cov-report xml
--verbose

[aliases]
Expand Down
7 changes: 6 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@ def setup_package():
needs_sphinx = {'build_sphinx', 'upload_docs'}.intersection(sys.argv)
sphinx = ['sphinx'] if needs_sphinx else []

cmake = ['cmake'] if 'arm' not in platform.machine() else []
cmake = []
# cmake = ['cmake']
# if 'arm' in platform.machine():
# print("ARM platform detected. Skipping cmake")
# cmake = []

setup(setup_requires=['six', 'pyscaffold>=2.5a0,<2.6a0'] + sphinx + cmake,
packages=['pyqrllib', ],
ext_modules=[CMakeExtension('pyqrllib')],
cmdclass=dict(build_ext=CMakeBuild),
use_pyscaffold=True)
Expand Down
80 changes: 80 additions & 0 deletions src/jswrapper/jswrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <emscripten.h>
#include <emscripten/bind.h>
#include <iostream>
#include <xmssFast.h>
#include <misc.h>
#include <xmss.h>

namespace {

class XmssWrapper
{
public:
XmssWrapper(const std::vector<unsigned char> &seed, unsigned char height) : _xmss(seed, height) {}

TSIGNATURE sign(const TMESSAGE &message) { return _xmss.sign(message); }

TKEY getSK() { return _xmss.getSK(); }
TKEY getPK() { return _xmss.getPK(); }
TSEED getSeed() { return _xmss.getSeed(); }
int getHeight() { return _xmss.getHeight(); }

TKEY getRoot() { return _xmss.getRoot(); }
TKEY getPKSeed() { return _xmss.getPKSeed(); }
TKEY getSKSeed() { return _xmss.getSKSeed(); }
TKEY getSKPRF() { return _xmss.getSKPRF(); }

unsigned int getIndex() { return _xmss.getIndex(); }
unsigned int setIndex(unsigned int new_index) { return _xmss.setIndex(new_index); }

static bool verify(const TMESSAGE &message,
const TSIGNATURE &signature,
const TKEY &pk,
unsigned char height)
{
return XmssFast::verify(message, signature, pk, height);
}

private:
XmssFast _xmss;
};

std::string EMSCRIPTEN_KEEPALIVE _bin2hstr(std::vector<unsigned char> input) {
return bin2hstr(input, 0);
}

std::vector<unsigned char> EMSCRIPTEN_KEEPALIVE _hstr2bin(std::string input) {
return hstr2bin(input);
}

std::vector<unsigned char> EMSCRIPTEN_KEEPALIVE _str2bin(std::string str) {
return str2bin(str);
}

using namespace emscripten;

EMSCRIPTEN_BINDINGS(my_module) {
register_vector<unsigned char>("VectorUChar");
function("bin2hstr", &_bin2hstr);
function("hstr2bin", &_hstr2bin);
function("str2bin", &_str2bin);

class_<XmssWrapper>("Xmss")
.constructor<TSEED, unsigned char>()
.function("getPK", &XmssWrapper::getPK)
.function("getSK", &XmssWrapper::getSK)
.function("getSeed", &XmssWrapper::getSeed)
.function("getHeight", &XmssWrapper::getHeight)

.function("getRoot", &XmssWrapper::getRoot)
.function("getPKSeed", &XmssWrapper::getPKSeed)
.function("getSKSeed", &XmssWrapper::getSKSeed)
.function("getSKPRF", &XmssWrapper::getSKPRF)

.function("getIndex", &XmssWrapper::getIndex)
.function("sign", &XmssWrapper::sign)
.class_function("verify", &XmssWrapper::verify)
;
}

}
5 changes: 3 additions & 2 deletions src/lib/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
#include <randombytes.h>
#include <iostream>
#include <unordered_map>
#include <stdexcept>

std::string bin2hstr(const std::vector<unsigned char> &vec, int wrap)
std::string bin2hstr(const std::vector<unsigned char> &vec, uint32_t wrap)
{
std::stringstream ss;

Expand All @@ -32,7 +33,7 @@ std::string bin2hstr(const std::vector<unsigned char> &vec, int wrap)
return ss.str();
}

std::string bin2hstr(const std::string &s, int wrap)
std::string bin2hstr(const std::string &s, uint32_t wrap)
{
return bin2hstr(str2bin(s), wrap);
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#define ADDRESS_HASH_SIZE 32

// FIXME: Move this to templates
std::string bin2hstr(const std::vector<unsigned char> &vec, int wrap = 0);
std::string bin2hstr(const std::string &vec, int wrap = 0);
std::string bin2hstr(const std::vector<unsigned char> &vec, uint32_t wrap = 0);
std::string bin2hstr(const std::string &vec, uint32_t wrap = 0);
std::vector<unsigned char> str2bin(const std::string &s);
std::vector<unsigned char> hstr2bin(const std::string &s) throw(std::invalid_argument);

Expand Down
Loading

0 comments on commit 4680eb2

Please sign in to comment.