├── .gitattributes ├── .gitignore ├── Cryptovium.sln ├── Cryptovium.vcxproj ├── Cryptovium.vcxproj.filters ├── README.md ├── license.md └── src ├── cryptovium ├── conf_cryptovium.h ├── cryptovium.c ├── cryptovium.h ├── cryptovium_ecc.c ├── cryptovium_kdf.c ├── cryptovium_rnd.c ├── cryptovium_sha.c ├── platform │ ├── compare_ct.c │ ├── compare_ct.h │ ├── hkdf.c │ ├── hkdf.h │ ├── pbkdf2.c │ ├── pbkdf2.h │ ├── windows │ │ ├── curve25519 │ │ │ ├── curve25519.c │ │ │ ├── curve25519.h │ │ │ └── ed25519 │ │ │ │ ├── additions │ │ │ │ ├── compare.c │ │ │ │ ├── compare.h │ │ │ │ ├── crypto_additions.h │ │ │ │ ├── crypto_hash_sha512.h │ │ │ │ ├── curve_sigs.c │ │ │ │ ├── curve_sigs.h │ │ │ │ ├── elligator.c │ │ │ │ ├── fe_isequal.c │ │ │ │ ├── fe_mont_rhs.c │ │ │ │ ├── fe_montx_to_edy.c │ │ │ │ ├── fe_sqrt.c │ │ │ │ ├── ge_is_small_order.c │ │ │ │ ├── ge_isneutral.c │ │ │ │ ├── ge_montx_to_p2.c │ │ │ │ ├── ge_montx_to_p3.c │ │ │ │ ├── ge_neg.c │ │ │ │ ├── ge_p3_to_montx.c │ │ │ │ ├── ge_scalarmult.c │ │ │ │ ├── ge_scalarmult_cofactor.c │ │ │ │ ├── keygen.c │ │ │ │ ├── keygen.h │ │ │ │ ├── open_modified.c │ │ │ │ ├── sc_clamp.c │ │ │ │ ├── sc_cmov.c │ │ │ │ ├── sc_neg.c │ │ │ │ ├── sign_modified.c │ │ │ │ ├── uopen_modified.c │ │ │ │ ├── usign_modified.c │ │ │ │ ├── utility.c │ │ │ │ ├── utility.h │ │ │ │ ├── vopen_modified.c │ │ │ │ ├── vsign_modified.c │ │ │ │ ├── vxeddsa.c │ │ │ │ ├── vxeddsa.h │ │ │ │ ├── xeddsa.c │ │ │ │ ├── xeddsa.h │ │ │ │ ├── zeroize.c │ │ │ │ └── zeroize.h │ │ │ │ ├── base.h │ │ │ │ ├── base2.h │ │ │ │ ├── d.h │ │ │ │ ├── d2.h │ │ │ │ ├── fe.h │ │ │ │ ├── fe_0.c │ │ │ │ ├── fe_1.c │ │ │ │ ├── fe_add.c │ │ │ │ ├── fe_cmov.c │ │ │ │ ├── fe_copy.c │ │ │ │ ├── fe_frombytes.c │ │ │ │ ├── fe_invert.c │ │ │ │ ├── fe_isnegative.c │ │ │ │ ├── fe_isnonzero.c │ │ │ │ ├── fe_mul.c │ │ │ │ ├── fe_neg.c │ │ │ │ ├── fe_pow22523.c │ │ │ │ ├── fe_sq.c │ │ │ │ ├── fe_sq2.c │ │ │ │ ├── fe_sub.c │ │ │ │ ├── fe_tobytes.c │ │ │ │ ├── ge.h │ │ │ │ ├── ge_add.c │ │ │ │ ├── ge_add.h │ │ │ │ ├── ge_double_scalarmult.c │ │ │ │ ├── ge_frombytes.c │ │ │ │ ├── ge_madd.c │ │ │ │ ├── ge_madd.h │ │ │ │ ├── ge_msub.c │ │ │ │ ├── ge_msub.h │ │ │ │ ├── ge_p1p1_to_p2.c │ │ │ │ ├── ge_p1p1_to_p3.c │ │ │ │ ├── ge_p2_0.c │ │ │ │ ├── ge_p2_dbl.c │ │ │ │ ├── ge_p2_dbl.h │ │ │ │ ├── ge_p3_0.c │ │ │ │ ├── ge_p3_dbl.c │ │ │ │ ├── ge_p3_to_cached.c │ │ │ │ ├── ge_p3_to_p2.c │ │ │ │ ├── ge_p3_tobytes.c │ │ │ │ ├── ge_precomp_0.c │ │ │ │ ├── ge_scalarmult_base.c │ │ │ │ ├── ge_sub.c │ │ │ │ ├── ge_sub.h │ │ │ │ ├── ge_tobytes.c │ │ │ │ ├── main │ │ │ │ └── main.c │ │ │ │ ├── nacl_includes │ │ │ │ ├── crypto_int32.h │ │ │ │ ├── crypto_int64.h │ │ │ │ ├── crypto_sign.h │ │ │ │ ├── crypto_sign_edwards25519sha512batch.h │ │ │ │ ├── crypto_uint32.h │ │ │ │ ├── crypto_uint64.h │ │ │ │ └── crypto_verify_32.h │ │ │ │ ├── nacl_sha512 │ │ │ │ ├── blocks.c │ │ │ │ └── hash.c │ │ │ │ ├── open.c │ │ │ │ ├── pow22523.h │ │ │ │ ├── pow225521.h │ │ │ │ ├── sc.h │ │ │ │ ├── sc_muladd.c │ │ │ │ ├── sc_reduce.c │ │ │ │ ├── sign.c │ │ │ │ ├── sqrtm1.h │ │ │ │ └── tests │ │ │ │ ├── tests.c │ │ │ │ └── tests.h │ │ ├── include_windows.h │ │ ├── mico-ecc │ │ │ ├── .gitignore │ │ │ ├── LICENSE.txt │ │ │ ├── README.md │ │ │ ├── asm_arm.inc │ │ │ ├── asm_arm_mult_square.inc │ │ │ ├── asm_arm_mult_square_umaal.inc │ │ │ ├── asm_avr.inc │ │ │ ├── asm_avr_mult_square.inc │ │ │ ├── curve-specific.inc │ │ │ ├── emk_project.py │ │ │ ├── emk_rules.py │ │ │ ├── platform-specific.inc │ │ │ ├── scripts │ │ │ │ ├── mult_arm.py │ │ │ │ ├── mult_avr.py │ │ │ │ ├── mult_avr_extra.py │ │ │ │ ├── square_arm.py │ │ │ │ └── square_avr.py │ │ │ ├── test │ │ │ │ ├── ecc_test │ │ │ │ │ └── ecc_test.ino │ │ │ │ ├── emk_rules.py │ │ │ │ ├── test_compress.c │ │ │ │ ├── test_compute.c │ │ │ │ ├── test_ecdh.c │ │ │ │ ├── test_ecdsa.c │ │ │ │ └── test_ecdsa_deterministic.c.example │ │ │ ├── types.h │ │ │ ├── uECC.c │ │ │ ├── uECC.h │ │ │ └── uECC_vli.h │ │ ├── sec_rnd.c │ │ ├── sec_rnd.h │ │ ├── sha256.c │ │ ├── sha256.h │ │ ├── sha512.c │ │ └── sha512.h │ ├── zeroize.c │ └── zeroize.h └── unit_tests │ ├── cryptovium_tests.c │ ├── cryptovium_tests.h │ ├── cvm_ut_fidou2f.c │ └── cvm_ut_sha.c └── main.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | 254 | # ========================= 255 | # Operating System Files 256 | # ========================= 257 | 258 | # OSX 259 | # ========================= 260 | 261 | .DS_Store 262 | .AppleDouble 263 | .LSOverride 264 | 265 | # Thumbnails 266 | ._* 267 | 268 | # Files that might appear in the root of a volume 269 | .DocumentRevisions-V100 270 | .fseventsd 271 | .Spotlight-V100 272 | .TemporaryItems 273 | .Trashes 274 | .VolumeIcon.icns 275 | 276 | # Directories potentially created on remote AFP share 277 | .AppleDB 278 | .AppleDesktop 279 | Network Trash Folder 280 | Temporary Items 281 | .apdisk 282 | 283 | # Windows 284 | # ========================= 285 | 286 | # Windows image file caches 287 | Thumbs.db 288 | ehthumbs.db 289 | 290 | # Folder config file 291 | Desktop.ini 292 | 293 | # Recycle Bin used on file shares 294 | $RECYCLE.BIN/ 295 | 296 | # Windows Installer files 297 | *.cab 298 | *.msi 299 | *.msm 300 | *.msp 301 | 302 | # Windows shortcuts 303 | *.lnk 304 | -------------------------------------------------------------------------------- /Cryptovium.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cryptovium", "Cryptovium.vcxproj", "{A72F5D82-7835-4E8A-9ECC-15F78674B5BB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {A72F5D82-7835-4E8A-9ECC-15F78674B5BB}.Debug|x64.ActiveCfg = Debug|x64 17 | {A72F5D82-7835-4E8A-9ECC-15F78674B5BB}.Debug|x64.Build.0 = Debug|x64 18 | {A72F5D82-7835-4E8A-9ECC-15F78674B5BB}.Debug|x86.ActiveCfg = Debug|Win32 19 | {A72F5D82-7835-4E8A-9ECC-15F78674B5BB}.Debug|x86.Build.0 = Debug|Win32 20 | {A72F5D82-7835-4E8A-9ECC-15F78674B5BB}.Release|x64.ActiveCfg = Release|x64 21 | {A72F5D82-7835-4E8A-9ECC-15F78674B5BB}.Release|x64.Build.0 = Release|x64 22 | {A72F5D82-7835-4E8A-9ECC-15F78674B5BB}.Release|x86.ActiveCfg = Release|Win32 23 | {A72F5D82-7835-4E8A-9ECC-15F78674B5BB}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cryptovium (aka CryptoVM) 2 | 3 | Cryptovium is an experimental virtual execution environment for cryptographic primitives written in C. It has its own byte-encoded instruction set and features eight individually addressable 256-bit registers that can act as a source or a destination for instruction operands. Instructions can also access external immediate data (read-only) that has been attached to the "CryptoVM instance" via a function call, and can send output data to a global "output buffer". It implements no branch conditions, only very simple compare and verify operations that return an appropriate error code on failure. All operands are length-checked by the interpreter, as are all writes to the global output buffer. 4 | 5 | 6 | The best way to understand Cryptovium is to study the unit tests. There is a full FIDO U2F register/authenticate implementation (from the perspective of a USB token) that adequately covers most use cases. 7 | 8 | 9 | Cryptovium is incomplete - currently only SHA2, CURVE25519, ECC SECP256R1, and key derivation functions are implemented. 10 | 11 | ####Again, this is just an experiment - use at your own risk. 12 | 13 | 14 | 15 | 16 | ## Acknowledgements 17 | 18 | curve25519 library from [Open Whisper Systems](https://github.com/WhisperSystems) 19 | 20 | micro-ecc library from [Ken MacKay](https://github.com/kmackay/micro-ecc) 21 | 22 | 23 | # License 24 | 25 | [GNU GPLv3](http://www.gnu.org/licenses/gpl-3.0.txt) 26 | -------------------------------------------------------------------------------- /src/cryptovium/conf_cryptovium.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/13/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #ifndef _CRYPTOVIUM_CONF_H_ 11 | #define _CRYPTOVIUM_CONF_H_ 12 | 13 | 14 | #define CVM_MAX_IMMEDIATE_EXTERNALS (8) 15 | 16 | 17 | #define CRYPTOVIUM_SUPPORT_SECURE_RANDOM (1) 18 | 19 | #define CRYPTOVIUM_SUPPORT_SHA256 (1) 20 | #define CRYPTOVIUM_SUPPORT_SHA256_INCREMENTAL (1) 21 | #define CRYPTOVIUM_SUPPORT_SHA512 (1) 22 | #define CRYPTOVIUM_SUPPORT_SHA512_INCREMENTAL (1) 23 | #define CRYPTOVIUM_SUPPORT_HMAC_SHA256 (1) 24 | #define CRYPTOVIUM_SUPPORT_HMAC_SHA256_INCREMENTAL (1) 25 | 26 | #define CRYPTOVIUM_SUPPORT_ECC_CURVE25519 (1) 27 | #define CRYPTOVIUM_SUPPORT_ECC_CURVE25519_SIGN (1) 28 | #define CRYPTOVIUM_SUPPORT_ECC_CURVE25519_VERIFY (1) 29 | 30 | #define CRYPTOVIUM_SUPPORT_ECC_ED25519_SIGN (0) 31 | #define CRYPTOVIUM_SUPPORT_ECC_ED25519_VERIFY (0) 32 | 33 | #define CRYPTOVIUM_SUPPORT_ECC_SECP256R1 (1) 34 | #define CRYPTOVIUM_SUPPORT_ECC_SECP256R1_SIGN (1) 35 | #define CRYPTOVIUM_SUPPORT_ECC_SECP256R1_VERIFY (1) 36 | #define CRYPTOVIUM_SUPPORT_ECC_SECP256R1_DER_ENCODE (1) 37 | #define CRYPTOVIUM_SUPPORT_ECC_SECP256R1_DER_DECODE (1) 38 | 39 | #define CRYPTOVIUM_SUPPORT_KDF_HKDF (1) 40 | #define CRYPTOVIUM_SUPPORT_KDF_PBKDF2 (1) 41 | 42 | 43 | #endif // _CRYPTOVIUM_CONF_H_ 44 | -------------------------------------------------------------------------------- /src/cryptovium/cryptovium.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/15/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #ifndef _CRYPTOVIUM_H_ 11 | #define _CRYPTOVIUM_H_ 12 | 13 | #include "conf_cryptovium.h" 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | #pragma pack(push, 1) 22 | 23 | typedef struct 24 | { 25 | uint8_t a[32]; 26 | uint8_t b[32]; 27 | uint8_t c[32]; 28 | uint8_t d[32]; 29 | uint8_t e[32]; 30 | uint8_t f[32]; 31 | uint8_t g[32]; 32 | uint8_t h[32]; 33 | } cvm_regs32_t; 34 | 35 | typedef struct 36 | { 37 | uint8_t ab[64]; 38 | uint8_t cd[64]; 39 | uint8_t ef[64]; 40 | uint8_t gh[64]; 41 | } cvm_regs64_t; 42 | 43 | typedef struct 44 | { 45 | uint8_t abcd[128]; 46 | uint8_t efgh[128]; 47 | } cvm_regs128_t; 48 | 49 | typedef union 50 | { 51 | cvm_regs32_t regs32; 52 | cvm_regs64_t regs64; 53 | cvm_regs128_t regs128; 54 | } cvm_regs_t; 55 | 56 | #pragma pack(pop) 57 | 58 | 59 | typedef enum 60 | { 61 | CVM_ERR_NONE, 62 | CVM_ERR_END_OF_STREAM, 63 | CVM_ERR_INVALID_REG, 64 | CVM_ERR_INVALID_OPERAND, 65 | CVM_ERR_INVALID_OPERAND_LENGTH, 66 | CVM_ERR_ENTROPY_SOURCE_FAILED, 67 | CVM_ERR_ZERO_DATA, 68 | CVM_ERR_NO_CONTEXT, 69 | CVM_ERR_NOT_IMPLEMENTED, 70 | CVM_ERR_BUFFER_OVERFLOW, 71 | CVM_ERR_COMPARE_FAILED, 72 | CVM_ERR_SIGNATURE_VERIFY_FAILED, 73 | CVM_ERR_DECODE_FAILED, 74 | CVM_ERR_NOT_INITIALIZED, 75 | CVM_ERR_IMM_EXT_OVERFLOW, 76 | CVM_ERR_INVALID_IMM_EXT, 77 | CVM_ERR_UNKNOWN 78 | } cvm_error_t; 79 | 80 | typedef enum 81 | { 82 | CVM_F_RESERVED = 0x00, 83 | 84 | // intrinsics 85 | CVM_F_MOVE = 0x01, // 2 operands - DST, SRC 86 | CVM_F_COMPARE = 0x02, // 2 operands 87 | CVM_F_ZEROIZE = 0x03, // 1 operand, DST=reg only 88 | 89 | // RND functions 90 | CVM_F_SECURE_RANDOM = 0x04, // 1 operand, DST=reg only 91 | 92 | // SHA functions 93 | CVM_F_SHA256 = 0x10, // 2 operands, DST, SRC 94 | CVM_F_SHA256_START = 0x11, // 0 operands (initializes SHA256 context) 95 | CVM_F_SHA256_UPDATE = 0x12, // 1 operand, SRC 96 | CVM_F_SHA256_FINISH = 0x13, // 1 operand, DST 97 | CVM_F_SHA512 = 0x14, // 2 operands, DST, SRC 98 | CVM_F_SHA512_START = 0x15, // 0 operands (initializes SHA512 context) 99 | CVM_F_SHA512_UPDATE = 0x16, // 1 operand, SRC 100 | CVM_F_SHA512_FINISH = 0x17, // 1 operand, DST 101 | CVM_F_HMAC_SHA256 = 0x18, // 3 operands, DST, SECRET, SRC 102 | CVM_F_HMAC_SHA256_START = 0x19, // 1 operand, SECRET 103 | CVM_F_HMAC_SHA256_UPDATE = 0x1a, // 1 operand, SRC 104 | CVM_F_HMAC_SHA256_FINISH = 0x1b, // 1 operand, DST 105 | 106 | // ECC functions 107 | CVM_F_ECC_CURVE25519_CLAMP_SECRET = 0x30, // 1 operand, KEY=reg only 108 | CVM_F_ECC_CURVE25519_COMPUTE_PUBLIC = 0x31, // 2 operands, PUBLIC, SECRET 109 | CVM_F_ECC_CURVE25519_COMPUTE_SHARED = 0x32, // 3 operands, SHARED, SECRET, PUBLIC 110 | CVM_F_ECC_CURVE25519_SIGN = 0x33, // 3 operands, SIGNATURE, SECRET, DATA 111 | CVM_F_ECC_CURVE25519_VERIFY = 0x34, // 3 operands, SIGNATURE, PUBLIC, DATA 112 | //CVM_F_ECC_ED25519_CLAMP_SECRET = 0x35, // 1 operand, KEY=reg only 113 | //CVM_F_ECC_ED25519_COMPUTE_PUBLIC = 0x36, // 2 operands, PUBLIC, SECRET 114 | //CVM_F_ECC_ED25519_SIGN = 0x37, // 3 operands, SIGNATURE, SECRET, DATA 115 | //CVM_F_ECC_ED25519_VERIFY = 0x38, // 3 operands, SIGNATURE, PUBLIC, DATA 116 | 117 | CVM_F_ECC_SECP256R1_COMPUTE_PUBLIC = 0x40, // 2 operands, PUBLIC, SECRET 118 | CVM_F_ECC_SECP256R1_COMPUTE_SHARED = 0x41, // 3 operands, SHARED, SECRET, PUBLIC 119 | CVM_F_ECC_SECP256R1_SIGN = 0x42, // 3 operands, SIGNATURE, SECRET, HASH 120 | CVM_F_ECC_SECP256R1_VERIFY = 0x43, // 3 operands, SIGNATURE, PUBLIC, HASH 121 | CVM_F_ECC_SECP256R1_DER_ENCODE = 0x44, // 2 operands, SIGNATURE_DER, SIGNATURE 122 | CVM_F_ECC_SECP256R1_DER_DECODE = 0x45, // 2 operands, SIGNATURE, SIGNATURE_DER 123 | 124 | // KDF functions 125 | CVM_F_HKDF = 0xf0, // 5 operands, OUTPUT, SALT, KEY, INFO, START_OFFSET 126 | CVM_F_PBKDF2_SHA256_HMAC = 0xf1, // 4 operands, DK, P, SALT, C 127 | } cvm_func_t; 128 | 129 | 130 | typedef enum 131 | { 132 | CVM_IMM_BUF = 0x00, // do not use CVM_IMM_BUF directly in an execution stream - use helper defines below 133 | CVM_REG32_A = 0x01, 134 | CVM_REG32_B = 0x02, 135 | CVM_REG32_C = 0x04, 136 | CVM_REG32_D = 0x08, 137 | CVM_REG32_E = 0x10, 138 | CVM_REG32_F = 0x20, 139 | CVM_REG32_G = 0x40, 140 | CVM_REG32_H = 0x80, 141 | CVM_REG64_AB = CVM_REG32_A | CVM_REG32_B, 142 | CVM_REG64_CD = CVM_REG32_C | CVM_REG32_D, 143 | CVM_REG64_EF = CVM_REG32_E | CVM_REG32_F, 144 | CVM_REG64_GH = CVM_REG32_G | CVM_REG32_H, 145 | CVM_REG128_ABCD = CVM_REG32_A | CVM_REG32_B | CVM_REG32_C | CVM_REG32_D, 146 | CVM_REG128_EFGH = CVM_REG32_E | CVM_REG32_F | CVM_REG32_G | CVM_REG32_H, 147 | CVM_EXTERNAL = 0xff 148 | } cvm_operand_t; 149 | 150 | // operand encoding helpers - use these instead of CVM_IMM_BUF directly 151 | #define CVM_IMMEDIATE CVM_IMM_BUF 152 | #define CVM_OUTPUT_BUFFER CVM_IMM_BUF, 0 153 | 154 | 155 | typedef struct 156 | { 157 | cvm_operand_t op; 158 | uint32_t sz; 159 | uint8_t* ptr; 160 | } cvm_param_t; 161 | 162 | 163 | cvm_error_t cvm_init(void); 164 | cvm_error_t cvm_import_external(const uint8_t* pdata, uint32_t sz_data); 165 | cvm_error_t cvm_execute_stream(const uint8_t* pstream, uint32_t sz_stream, uint8_t* pbuffer, uint32_t sz_buffer, uint32_t* psz_out); 166 | void cvm_zeroize(void); 167 | cvm_regs_t* cvm_get_regs(void); // for unit test dump 168 | 169 | #ifdef __cplusplus 170 | } 171 | #endif 172 | 173 | #endif // _CRYPTOVIUM_H_ 174 | -------------------------------------------------------------------------------- /src/cryptovium/cryptovium_kdf.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | #include "cryptovium.h" 10 | #include "hkdf.h" 11 | #include "pbkdf2.h" 12 | #include 13 | #include 14 | 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | cvm_error_t cvm_f_kdf_hkdf(cvm_param_t* op_output, cvm_param_t* op_salt, cvm_param_t* op_key, cvm_param_t* op_info, cvm_param_t* op_start_offset) 18 | { 19 | if ((op_output->op == CVM_IMM_BUF) || (op_output->op == CVM_EXTERNAL)) 20 | return CVM_ERR_INVALID_OPERAND; 21 | 22 | hkdf_derive_secrets(*((uint8_t*)op_start_offset->ptr), op_salt->ptr, op_salt->sz, op_key->ptr, op_key->sz, op_info->ptr, op_info->sz, op_output->ptr, op_output->sz); 23 | 24 | return CVM_ERR_NONE; 25 | } 26 | 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | cvm_error_t cvm_f_kdf_pbkdf2_sha256_hmac(cvm_param_t* op_dk, cvm_param_t* op_p, cvm_param_t* op_salt, cvm_param_t* op_c) 30 | { 31 | if ((op_dk->op == CVM_IMM_BUF) || (op_dk->op == CVM_EXTERNAL)) 32 | return CVM_ERR_INVALID_OPERAND; 33 | 34 | pbkdf2_sha256_hmac(op_p->ptr, op_p->sz, op_salt->ptr, op_salt->sz, *((uint8_t*)op_c->ptr), op_dk->ptr, op_dk->sz); 35 | 36 | return CVM_ERR_NONE; 37 | } 38 | -------------------------------------------------------------------------------- /src/cryptovium/cryptovium_rnd.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | #include "cryptovium.h" 10 | #include "sec_rnd.h" 11 | #include 12 | #include 13 | 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | cvm_error_t cvm_f_secure_random(cvm_param_t* op_dst) 17 | { 18 | if ((op_dst->op == CVM_IMM_BUF) || (op_dst->op == CVM_EXTERNAL)) 19 | return CVM_ERR_INVALID_OPERAND; 20 | 21 | if (!secure_random(op_dst->ptr, op_dst->sz)) 22 | return CVM_ERR_ENTROPY_SOURCE_FAILED; 23 | 24 | return CVM_ERR_NONE; 25 | } 26 | -------------------------------------------------------------------------------- /src/cryptovium/cryptovium_sha.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | #include "cryptovium.h" 10 | #include "zeroize.h" 11 | #include "compare_ct.h" 12 | #include "sha256.h" 13 | #include "sha512.h" 14 | #include 15 | #include 16 | 17 | 18 | static sha256_context context_sha256; 19 | static sha512_context context_sha512; 20 | static sha256_context context_hmac_sha256; 21 | 22 | static bool sha256_started = false; 23 | static bool sha512_started = false; 24 | static bool hmac_sha256_started = false; 25 | 26 | 27 | //////////////////////////////////////////////////////////////////////////////// 28 | // forward declarations 29 | //////////////////////////////////////////////////////////////////////////////// 30 | extern cvm_error_t _cvm_check_dst_op_size(cvm_param_t* op, uint8_t sz); 31 | 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | cvm_error_t cvm_f_sha256(cvm_param_t* op_hash, cvm_param_t* op_data) 35 | { 36 | cvm_error_t ret; 37 | 38 | // check destination size 39 | ret = _cvm_check_dst_op_size(op_hash, SHA256_HASH_SIZE); 40 | if (ret != CVM_ERR_NONE) return ret; 41 | 42 | sha256(op_data->ptr, op_data->sz, op_hash->ptr); 43 | 44 | return CVM_ERR_NONE; 45 | } 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | cvm_error_t cvm_f_sha256_start() 49 | { 50 | if (sha256_started) 51 | return CVM_ERR_NO_CONTEXT; 52 | 53 | sha256_init(&context_sha256); 54 | sha256_started = true; 55 | 56 | return CVM_ERR_NONE; 57 | } 58 | 59 | //////////////////////////////////////////////////////////////////////////////// 60 | cvm_error_t cvm_f_sha256_update(cvm_param_t* op_data) 61 | { 62 | if (sha256_started == false) 63 | return CVM_ERR_NO_CONTEXT; 64 | 65 | sha256_update(&context_sha256, op_data->ptr, op_data->sz); 66 | 67 | return CVM_ERR_NONE; 68 | } 69 | 70 | //////////////////////////////////////////////////////////////////////////////// 71 | cvm_error_t cvm_f_sha256_finish(cvm_param_t* op_hash) 72 | { 73 | cvm_error_t ret; 74 | 75 | if (sha256_started == false) 76 | return CVM_ERR_NO_CONTEXT; 77 | 78 | // check destination size 79 | ret = _cvm_check_dst_op_size(op_hash, SHA256_HASH_SIZE); 80 | if (ret != CVM_ERR_NONE) return ret; 81 | 82 | sha256_finish(&context_sha256, op_hash->ptr); 83 | 84 | sha256_started = false; 85 | 86 | return CVM_ERR_NONE; 87 | } 88 | 89 | //////////////////////////////////////////////////////////////////////////////// 90 | cvm_error_t cvm_f_sha512(cvm_param_t* op_hash, cvm_param_t* op_data) 91 | { 92 | cvm_error_t ret; 93 | 94 | // check destination size 95 | ret = _cvm_check_dst_op_size(op_hash, SHA512_HASH_SIZE); 96 | if (ret != CVM_ERR_NONE) return ret; 97 | 98 | sha512(op_data->ptr, op_data->sz, op_hash->ptr); 99 | 100 | return CVM_ERR_NONE; 101 | } 102 | 103 | //////////////////////////////////////////////////////////////////////////////// 104 | cvm_error_t cvm_f_sha512_start() 105 | { 106 | if (sha512_started) 107 | return CVM_ERR_NO_CONTEXT; 108 | 109 | sha512_init(&context_sha512); 110 | sha512_started = true; 111 | 112 | return CVM_ERR_NONE; 113 | } 114 | 115 | //////////////////////////////////////////////////////////////////////////////// 116 | cvm_error_t cvm_f_sha512_update(cvm_param_t* op_data) 117 | { 118 | if (sha512_started == false) 119 | return CVM_ERR_NO_CONTEXT; 120 | 121 | sha512_update(&context_sha512, op_data->ptr, op_data->sz); 122 | 123 | return CVM_ERR_NONE; 124 | } 125 | 126 | //////////////////////////////////////////////////////////////////////////////// 127 | cvm_error_t cvm_f_sha512_finish(cvm_param_t* op_hash) 128 | { 129 | cvm_error_t ret; 130 | 131 | if (sha512_started == false) 132 | return CVM_ERR_NO_CONTEXT; 133 | 134 | // check destination size 135 | ret = _cvm_check_dst_op_size(op_hash, SHA512_HASH_SIZE); 136 | if (ret != CVM_ERR_NONE) return ret; 137 | 138 | sha512_finish(&context_sha512, op_hash->ptr); 139 | 140 | sha512_started = false; 141 | 142 | return CVM_ERR_NONE; 143 | } 144 | 145 | //////////////////////////////////////////////////////////////////////////////// 146 | cvm_error_t cvm_f_hmac_sha256(cvm_param_t* op_hash, cvm_param_t* op_secret, cvm_param_t* op_data) 147 | { 148 | cvm_error_t ret; 149 | 150 | // check secret for zeros 151 | if (compare_constant_time_zero(op_secret->ptr, op_secret->sz)) 152 | return CVM_ERR_ZERO_DATA; 153 | 154 | // check destination size 155 | ret = _cvm_check_dst_op_size(op_hash, SHA256_HASH_SIZE); 156 | if (ret != CVM_ERR_NONE) return ret; 157 | 158 | sha256_hmac(op_secret->ptr, op_secret->sz, op_data->ptr, op_data->sz, op_hash->ptr); 159 | 160 | return CVM_ERR_NONE; 161 | } 162 | 163 | //////////////////////////////////////////////////////////////////////////////// 164 | cvm_error_t cvm_f_hmac_sha256_start(cvm_param_t* op_secret) 165 | { 166 | // check secret for zeros 167 | if (compare_constant_time_zero(op_secret->ptr, op_secret->sz)) 168 | return CVM_ERR_ZERO_DATA; 169 | 170 | if (hmac_sha256_started) 171 | return CVM_ERR_NO_CONTEXT; 172 | 173 | sha256_hmac_init(&context_hmac_sha256, op_secret->ptr, op_secret->sz); 174 | hmac_sha256_started = true; 175 | 176 | return CVM_ERR_NONE; 177 | } 178 | 179 | //////////////////////////////////////////////////////////////////////////////// 180 | cvm_error_t cvm_f_hmac_sha256_update(cvm_param_t* op_data) 181 | { 182 | if (hmac_sha256_started == false) 183 | return CVM_ERR_NO_CONTEXT; 184 | 185 | sha256_hmac_update(&context_hmac_sha256, op_data->ptr, op_data->sz); 186 | 187 | return CVM_ERR_NONE; 188 | } 189 | 190 | //////////////////////////////////////////////////////////////////////////////// 191 | cvm_error_t cvm_f_hmac_sha256_finish(cvm_param_t* op_hash) 192 | { 193 | cvm_error_t ret; 194 | 195 | if (hmac_sha256_started == false) 196 | return CVM_ERR_NO_CONTEXT; 197 | 198 | // check destination size 199 | ret = _cvm_check_dst_op_size(op_hash, SHA256_HASH_SIZE); 200 | if (ret != CVM_ERR_NONE) return ret; 201 | 202 | sha256_hmac_finish(&context_hmac_sha256, op_hash->ptr); 203 | 204 | hmac_sha256_started = false; 205 | 206 | return CVM_ERR_NONE; 207 | } 208 | -------------------------------------------------------------------------------- /src/cryptovium/platform/compare_ct.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/05/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #include "compare_ct.h" 11 | 12 | 13 | bool compare_constant_time(const uint8_t* a, const uint8_t* b, const uint32_t sz) 14 | { 15 | uint8_t c; 16 | uint32_t i; 17 | 18 | c = 0; 19 | 20 | for (i = 0; i < sz; ++i) 21 | c |= (a[i] ^ b[i]); 22 | 23 | if (c == 0) // match 24 | return true; 25 | else 26 | return false; 27 | } 28 | 29 | bool compare_constant_time_zero(const uint8_t* p, const uint32_t sz) 30 | { 31 | uint8_t c; 32 | uint32_t i; 33 | 34 | c = 0; 35 | 36 | for (i = 0; i < sz; ++i) 37 | c |= (p[i] ^ 0); 38 | 39 | if (c == 0) // match 40 | return true; 41 | else 42 | return false; 43 | } -------------------------------------------------------------------------------- /src/cryptovium/platform/compare_ct.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/05/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #ifndef _COMPARE_CT_H_ 11 | #define _COMPARE_CT_H_ 12 | 13 | #include 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | bool compare_constant_time(const uint8_t* a, const uint8_t* b, const uint32_t sz); 22 | bool compare_constant_time_zero(const uint8_t* p, const uint32_t sz); 23 | 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif // _COMPARE_CT_H_ 30 | -------------------------------------------------------------------------------- /src/cryptovium/platform/hkdf.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/13/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | #ifndef _HKDF_H_ 10 | #define _HKDF_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | void hkdf_derive_secrets( 22 | size_t n_start_offset, 23 | const uint8_t* salt, 24 | size_t salt_len, 25 | const uint8_t* input_key_material, 26 | size_t input_key_material_len, 27 | const uint8_t* info, 28 | size_t info_len, 29 | uint8_t* output, 30 | size_t output_len); 31 | 32 | bool hkdf_self_test(void); 33 | 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif // _HKDF_H_ 40 | -------------------------------------------------------------------------------- /src/cryptovium/platform/pbkdf2.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/13/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #include "pbkdf2.h" 11 | #include "sha256.h" 12 | #include "zeroize.h" 13 | #include "compare_ct.h" 14 | #include 15 | 16 | 17 | //////////////////////////////////////////////////////////////////////////////// 18 | static inline uint32_t _BE32(const uint32_t u) 19 | { 20 | uint32_t v; 21 | 22 | v = ((u << 8) & 0xFF00FF00 ) | ((u >> 8) & 0xFF00FF ); 23 | return (v << 16) | (v >> 16); 24 | } 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | void pbkdf2_sha256_hmac(const uint8_t* P, const uint32_t szP, const uint8_t* S, const uint32_t szS, const uint32_t c, uint8_t* DK, const uint32_t dkLen) 28 | { 29 | sha256_context ctx; 30 | uint8_t f[SHA256_HASH_SIZE]; 31 | uint8_t g[SHA256_HASH_SIZE]; 32 | uint32_t n, i, j, k; 33 | 34 | // skip dkLen check (must be <= (2^32 - 1) * HMAC_SHA256_SIZE_BYTES 35 | 36 | // compute total number of HMAC_SHA256 blocks 37 | n = dkLen / SHA256_HASH_SIZE; 38 | if (dkLen & (SHA256_HASH_SIZE - 1)) 39 | n++; 40 | 41 | for (i = 1; i <= n; i++) 42 | { 43 | j = _BE32(i); // convert i to big endian 44 | 45 | // compute sha256-hmac 46 | sha256_hmac_init(&ctx, P, szP); 47 | sha256_hmac_update(&ctx, S, szS); 48 | sha256_hmac_update(&ctx, (uint8_t*)&j, sizeof(uint32_t)); 49 | sha256_hmac_finish(&ctx, g); 50 | 51 | memcpy(f, g, SHA256_HASH_SIZE); // copy to f 52 | 53 | for (j = 1; j < c; j++) 54 | { 55 | sha256_hmac(P, szP, g, SHA256_HASH_SIZE, g); 56 | 57 | for (k = 0; k < SHA256_HASH_SIZE; k++) 58 | f[k] ^= g[k]; 59 | } 60 | 61 | if (i == n && (dkLen & (SHA256_HASH_SIZE - 1))) 62 | memcpy(DK + SHA256_HASH_SIZE * (i - 1), f, dkLen & (SHA256_HASH_SIZE - 1)); 63 | else 64 | memcpy(DK + SHA256_HASH_SIZE * (i - 1), f, SHA256_HASH_SIZE); 65 | } 66 | 67 | zeroize(f, sizeof(f)); 68 | zeroize(g, sizeof(g)); 69 | } 70 | 71 | //////////////////////////////////////////////////////////////////////////////// 72 | bool pbkdf2_self_test(void) 73 | { 74 | const uint8_t p1[] = "password"; 75 | const uint8_t s1[] = "salt"; 76 | const uint8_t p2[] = "passwordPASSWORDpassword"; 77 | const uint8_t s2[] = "saltSALTsaltSALTsaltSALTsaltSALTsalt"; 78 | const uint8_t p3[] = "pass\0word"; 79 | const uint8_t s3[] = "sa\0lt"; 80 | 81 | const uint8_t dk1[] = { 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, 82 | 0xa8, 0x65, 0x48, 0xc9 }; 83 | 84 | const uint8_t dk2[] = { 0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, 85 | 0x2a, 0x30, 0x3f, 0x8e }; 86 | 87 | const uint8_t dk3[] = { 0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, 88 | 0x96, 0x28, 0x93, 0xa0 }; 89 | 90 | //const uint8_t dk4[] = { 0xcf, 0x81, 0xc6, 0x6f, 0xe8, 0xcf, 0xc0, 0x4d, 0x1f, 0x31, 0xec, 0xb6, 0x5d, 0xab, 0x40, 0x89, 91 | // 0xf7, 0xf1, 0x79, 0xe8 }; 92 | 93 | const uint8_t dk5[] = { 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, 0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf, 94 | 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18, 0x1c }; 95 | 96 | const uint8_t dk6[] = { 0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89, 0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87 }; 97 | 98 | uint8_t dk[25]; 99 | 100 | pbkdf2_sha256_hmac(p1, (sizeof(p1) - 1), s1, (sizeof(s1) - 1), 1, dk, 20); 101 | if (compare_constant_time(dk, dk1, 20) == false) return false; 102 | 103 | pbkdf2_sha256_hmac(p1, (sizeof(p1) - 1), s1, (sizeof(s1) - 1), 2, dk, 20); 104 | if (compare_constant_time(dk, dk2, 20) == false) return false; 105 | 106 | pbkdf2_sha256_hmac(p1, (sizeof(p1) - 1), s1, (sizeof(s1) - 1), 4096, dk, 20); 107 | if (compare_constant_time(dk, dk3, 20) == false) return false; 108 | 109 | //pbkdf2_sha256_hmac(p1, (sizeof(p1) - 1), s1, (sizeof(s1) - 1), 16777216, dk, 20); 110 | //if (compare_constant_time(dk, dk4, 20) == false) return false; 111 | 112 | pbkdf2_sha256_hmac(p2, (sizeof(p2) - 1), s2, (sizeof(s2) - 1), 4096, dk, 25); 113 | if (compare_constant_time(dk, dk5, 25) == false) return false; 114 | 115 | pbkdf2_sha256_hmac(p3, (sizeof(p3) - 1), s3, (sizeof(s3) - 1), 4096, dk, 16); 116 | if (compare_constant_time(dk, dk6, 16) == false) return false; 117 | 118 | return true; 119 | } 120 | 121 | -------------------------------------------------------------------------------- /src/cryptovium/platform/pbkdf2.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/13/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #ifndef _PBKDF2_H_ 11 | #define _PBKDF2_H_ 12 | 13 | #include 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | void pbkdf2_sha256_hmac(const uint8_t* P, const uint32_t szP, const uint8_t* S, const uint32_t szS, const uint32_t c, uint8_t* DK, const uint32_t dkLen); 22 | bool pbkdf2_self_test(void); 23 | 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif // _PBKDF2_H_ 30 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/curve25519.h: -------------------------------------------------------------------------------- 1 | #ifndef CURVE25519_H 2 | #define CURVE25519_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | 9 | #define CURVE25519_KEY_SIZE 32 10 | 11 | extern void curve25519_scalarmult(uint8_t* r, const uint8_t* s, const uint8_t* p); 12 | extern void curve25519_scalarmult_base(uint8_t* q, const uint8_t* n); 13 | void curve25519_prepare_secret_key(uint8_t s[32]); 14 | 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/compare.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "compare.h" 3 | 4 | /* Const-time comparison from SUPERCOP, but here it's only used for 5 | signature verification, so doesn't need to be const-time. But 6 | copied the nacl version anyways. */ 7 | int crypto_verify_32_ref(const unsigned char *x, const unsigned char *y) 8 | { 9 | unsigned int differentbits = 0; 10 | #define F(i) differentbits |= x[i] ^ y[i]; 11 | F(0) 12 | F(1) 13 | F(2) 14 | F(3) 15 | F(4) 16 | F(5) 17 | F(6) 18 | F(7) 19 | F(8) 20 | F(9) 21 | F(10) 22 | F(11) 23 | F(12) 24 | F(13) 25 | F(14) 26 | F(15) 27 | F(16) 28 | F(17) 29 | F(18) 30 | F(19) 31 | F(20) 32 | F(21) 33 | F(22) 34 | F(23) 35 | F(24) 36 | F(25) 37 | F(26) 38 | F(27) 39 | F(28) 40 | F(29) 41 | F(30) 42 | F(31) 43 | return (1 & ((differentbits - 1) >> 8)) - 1; 44 | } 45 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/compare.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPARE_H__ 2 | #define __COMPARE_H__ 3 | 4 | int crypto_verify_32_ref(const unsigned char *b1, const unsigned char *b2); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/crypto_additions.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CRYPTO_ADDITIONS__ 3 | #define __CRYPTO_ADDITIONS__ 4 | 5 | #include "crypto_uint32.h" 6 | #include "fe.h" 7 | #include "ge.h" 8 | 9 | #define MAX_MSG_LEN 256 10 | 11 | void sc_neg(unsigned char *b, const unsigned char *a); 12 | void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b); 13 | 14 | int fe_isequal(const fe f, const fe g); 15 | void fe_mont_rhs(fe v2, const fe u); 16 | void fe_montx_to_edy(fe y, const fe u); 17 | void fe_sqrt(fe b, const fe a); 18 | 19 | int ge_is_small_order(const ge_p3 *p); 20 | int ge_isneutral(const ge_p3* q); 21 | void ge_neg(ge_p3* r, const ge_p3 *p); 22 | void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit); 23 | void ge_p3_to_montx(fe u, const ge_p3 *p); 24 | void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A); 25 | void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p); 26 | 27 | void elligator(fe u, const fe r); 28 | void hash_to_point(ge_p3* p, const unsigned char* msg, const unsigned long in_len); 29 | void calculate_Bv(ge_p3* Bv, 30 | unsigned char* buf, 31 | const unsigned char* A, 32 | const unsigned char* msg, const unsigned long msg_len); 33 | void calculate_Bv_and_V(ge_p3* Bv, 34 | unsigned char* V, 35 | unsigned char* buf, 36 | const unsigned char* a, 37 | const unsigned char* A, 38 | const unsigned char* msg, const unsigned long msg_len); 39 | 40 | int crypto_sign_modified( 41 | unsigned char *sm, 42 | const unsigned char *m,unsigned long long mlen, 43 | const unsigned char *sk, /* Curve/Ed25519 private key */ 44 | const unsigned char *pk, /* Ed25519 public key */ 45 | const unsigned char *random /* 64 bytes random to hash into nonce */ 46 | ); 47 | 48 | int crypto_sign_open_modified( 49 | unsigned char *m, 50 | const unsigned char *sm,unsigned long long smlen, 51 | const unsigned char *pk 52 | ); 53 | 54 | int crypto_vsign_modified( 55 | unsigned char *sm, 56 | const unsigned char *M,unsigned long Mlen, 57 | const unsigned char *a, 58 | const unsigned char *A, 59 | const unsigned char *random, 60 | const ge_p3 *Bu, 61 | const unsigned char *U); 62 | 63 | int crypto_vsign_open_modified( 64 | unsigned char *m, 65 | const unsigned char *sm,unsigned long long smlen, 66 | const unsigned char *pk, const ge_p3* Bu); 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/crypto_hash_sha512.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_hash_sha512_H 2 | #define crypto_hash_sha512_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | extern int crypto_hash_sha512(unsigned char *,const unsigned char *,unsigned long long); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/curve_sigs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ge.h" 4 | #include "curve_sigs.h" 5 | #include "crypto_sign.h" 6 | #include "crypto_additions.h" 7 | 8 | int curve25519_sign(unsigned char* signature_out, 9 | const unsigned char* curve25519_privkey, 10 | const unsigned char* msg, const unsigned long msg_len, 11 | const unsigned char* random) 12 | { 13 | ge_p3 ed_pubkey_point; /* Ed25519 pubkey point */ 14 | unsigned char ed_pubkey[32]; /* Ed25519 encoded pubkey */ 15 | unsigned char *sigbuf; /* working buffer */ 16 | unsigned char sign_bit = 0; 17 | 18 | if ((sigbuf = malloc(msg_len + 128)) == 0) { 19 | memset(signature_out, 0, 64); 20 | return -1; 21 | } 22 | 23 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 24 | ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); 25 | ge_p3_tobytes(ed_pubkey, &ed_pubkey_point); 26 | 27 | sign_bit = ed_pubkey[31] & 0x80; 28 | 29 | /* Perform an Ed25519 signature with explicit private key */ 30 | crypto_sign_modified(sigbuf, msg, msg_len, curve25519_privkey, 31 | ed_pubkey, random); 32 | 33 | memmove(signature_out, sigbuf, 64); 34 | 35 | /* Encode the sign bit into signature (in unused high bit of S) */ 36 | signature_out[63] &= 0x7F; /* bit should be zero already, but just in case */ 37 | signature_out[63] |= sign_bit; 38 | 39 | free(sigbuf); 40 | return 0; 41 | } 42 | 43 | int curve25519_verify(const unsigned char* signature, 44 | const unsigned char* curve25519_pubkey, 45 | const unsigned char* msg, const unsigned long msg_len) 46 | { 47 | fe u; 48 | fe y; 49 | unsigned char ed_pubkey[32]; 50 | unsigned char *verifybuf = NULL; /* working buffer */ 51 | unsigned char *verifybuf2 = NULL; /* working buffer #2 */ 52 | int result; 53 | 54 | if ((verifybuf = malloc(msg_len + 64)) == 0) { 55 | result = -1; 56 | goto err; 57 | } 58 | 59 | if ((verifybuf2 = malloc(msg_len + 64)) == 0) { 60 | result = -1; 61 | goto err; 62 | } 63 | 64 | /* Convert the Curve25519 public key into an Ed25519 public key. In 65 | particular, convert Curve25519's "montgomery" x-coordinate (u) into an 66 | Ed25519 "edwards" y-coordinate: 67 | 68 | y = (u - 1) / (u + 1) 69 | 70 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 71 | 72 | Then move the sign bit into the pubkey from the signature. 73 | */ 74 | fe_frombytes(u, curve25519_pubkey); 75 | fe_montx_to_edy(y, u); 76 | fe_tobytes(ed_pubkey, y); 77 | 78 | /* Copy the sign bit, and remove it from signature */ 79 | ed_pubkey[31] &= 0x7F; /* bit should be zero already, but just in case */ 80 | ed_pubkey[31] |= (signature[63] & 0x80); 81 | memmove(verifybuf, signature, 64); 82 | verifybuf[63] &= 0x7F; 83 | 84 | memmove(verifybuf+64, msg, msg_len); 85 | 86 | /* Then perform a normal Ed25519 verification, return 0 on success */ 87 | /* The below call has a strange API: */ 88 | /* verifybuf = R || S || message */ 89 | /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets 90 | replaced with pubkey for hashing */ 91 | result = crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); 92 | 93 | err: 94 | 95 | if (verifybuf != NULL) { 96 | free(verifybuf); 97 | } 98 | 99 | if (verifybuf2 != NULL) { 100 | free(verifybuf2); 101 | } 102 | 103 | return result; 104 | } 105 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/curve_sigs.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CURVE_SIGS_H__ 3 | #define __CURVE_SIGS_H__ 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | /* returns 0 on success */ 9 | int curve25519_sign(unsigned char* signature_out, /* 64 bytes */ 10 | const unsigned char* curve25519_privkey, /* 32 bytes */ 11 | const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ 12 | const unsigned char* random); /* 64 bytes */ 13 | 14 | /* returns 0 on success */ 15 | int curve25519_verify(const unsigned char* signature, /* 64 bytes */ 16 | const unsigned char* curve25519_pubkey, /* 32 bytes */ 17 | const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/elligator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "ge.h" 4 | #include "crypto_uint32.h" 5 | #include "crypto_hash_sha512.h" 6 | #include "crypto_additions.h" 7 | 8 | unsigned int legendre_is_nonsquare(fe in) 9 | { 10 | fe temp; 11 | fe_pow22523(temp, in); /* temp = in^((q-5)/8) */ 12 | fe_sq(temp, temp); /* in^((q-5)/4) */ 13 | fe_sq(temp, temp); /* in^((q-5)/2) */ 14 | fe_mul(temp, temp, in); /* in^((q-3)/2) */ 15 | fe_mul(temp, temp, in); /* in^((q-1)/2) */ 16 | 17 | /* temp is now the Legendre symbol: 18 | * 1 = square 19 | * 0 = input is zero 20 | * -1 = nonsquare 21 | */ 22 | unsigned char bytes[32]; 23 | fe_tobytes(bytes, temp); 24 | return 1 & bytes[31]; 25 | } 26 | 27 | void elligator(fe u, const fe r) 28 | { 29 | /* r = input 30 | * x = -A/(1+2r^2) # 2 is nonsquare 31 | * e = (x^3 + Ax^2 + x)^((q-1)/2) # legendre symbol 32 | * if e == 1 (square) or e == 0 (because x == 0 and 2r^2 + 1 == 0) 33 | * u = x 34 | * if e == -1 (nonsquare) 35 | * u = -x - A 36 | */ 37 | fe A, one, twor2, twor2plus1, twor2plus1inv; 38 | fe x, e, Atemp, uneg; 39 | unsigned int nonsquare; 40 | 41 | fe_1(one); 42 | fe_0(A); 43 | A[0] = 486662; /* A = 486662 */ 44 | 45 | fe_sq2(twor2, r); /* 2r^2 */ 46 | fe_add(twor2plus1, twor2, one); /* 1+2r^2 */ 47 | fe_invert(twor2plus1inv, twor2plus1); /* 1/(1+2r^2) */ 48 | fe_mul(x, twor2plus1inv, A); /* A/(1+2r^2) */ 49 | fe_neg(x, x); /* x = -A/(1+2r^2) */ 50 | 51 | fe_mont_rhs(e, x); /* e = x^3 + Ax^2 + x */ 52 | nonsquare = legendre_is_nonsquare(e); 53 | 54 | fe_0(Atemp); 55 | fe_cmov(Atemp, A, nonsquare); /* 0, or A if nonsquare */ 56 | fe_add(u, x, Atemp); /* x, or x+A if nonsquare */ 57 | fe_neg(uneg, u); /* -x, or -x-A if nonsquare */ 58 | fe_cmov(u, uneg, nonsquare); /* x, or -x-A if nonsquare */ 59 | } 60 | 61 | void hash_to_point(ge_p3* p, const unsigned char* in, const unsigned long in_len) 62 | { 63 | unsigned char hash[64]; 64 | fe h, u; 65 | unsigned char sign_bit; 66 | ge_p3 p3; 67 | 68 | crypto_hash_sha512(hash, in, in_len); 69 | 70 | /* take the high bit as Edwards sign bit */ 71 | sign_bit = (hash[31] & 0x80) >> 7; 72 | hash[31] &= 0x7F; 73 | fe_frombytes(h, hash); 74 | elligator(u, h); 75 | 76 | ge_montx_to_p3(&p3, u, sign_bit); 77 | ge_scalarmult_cofactor(p, &p3); 78 | } 79 | 80 | 81 | void calculate_Bv(ge_p3* Bv, 82 | unsigned char* buf, 83 | const unsigned char* A, 84 | const unsigned char* msg, const unsigned long msg_len) 85 | { 86 | int count; 87 | 88 | /* Calculate SHA512(label(2) || A || msg) */ 89 | buf[0] = 0xFD; 90 | for (count = 1; count < 32; count++) 91 | buf[count] = 0xFF; 92 | memmove(buf+32, A, 32); 93 | memmove(buf+64, msg, msg_len); 94 | 95 | hash_to_point(Bv, buf, 64 + msg_len); 96 | } 97 | 98 | 99 | void calculate_Bv_and_V(ge_p3* Bv, 100 | unsigned char* V, 101 | unsigned char* buf, 102 | const unsigned char* a, 103 | const unsigned char* A, 104 | const unsigned char* msg, const unsigned long msg_len) 105 | { 106 | ge_p3 p3; 107 | 108 | calculate_Bv(Bv, buf, A, msg, msg_len); 109 | ge_scalarmult(&p3, a, Bv); 110 | ge_p3_tobytes(V, &p3); 111 | } 112 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/fe_isequal.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_verify_32.h" 3 | 4 | /* 5 | return 1 if f == g 6 | return 0 if f != g 7 | */ 8 | 9 | int fe_isequal(const fe f, const fe g) 10 | { 11 | fe h; 12 | fe_sub(h, f, g); 13 | return 1 ^ (1 & (fe_isnonzero(h) >> 8)); 14 | } 15 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/fe_mont_rhs.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_mont_rhs(fe v2, fe u) { 4 | fe A, one; 5 | fe u2, Au, inner; 6 | 7 | fe_1(one); 8 | fe_0(A); 9 | A[0] = 486662; /* A = 486662 */ 10 | 11 | fe_sq(u2, u); /* u^2 */ 12 | fe_mul(Au, A, u); /* Au */ 13 | fe_add(inner, u2, Au); /* u^2 + Au */ 14 | fe_add(inner, inner, one); /* u^2 + Au + 1 */ 15 | fe_mul(v2, u, inner); /* u(u^2 + Au + 1) */ 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/fe_montx_to_edy.c: -------------------------------------------------------------------------------- 1 | 2 | #include "fe.h" 3 | #include "crypto_additions.h" 4 | 5 | void fe_montx_to_edy(fe y, const fe u) 6 | { 7 | /* 8 | y = (u - 1) / (u + 1) 9 | 10 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 11 | */ 12 | fe one, um1, up1; 13 | 14 | fe_1(one); 15 | fe_sub(um1, u, one); 16 | fe_add(up1, u, one); 17 | fe_invert(up1, up1); 18 | fe_mul(y, um1, up1); 19 | } 20 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/fe_sqrt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "crypto_additions.h" 4 | 5 | /* sqrt(-1) */ 6 | static unsigned char i_bytes[32] = { 7 | 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4, 8 | 0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f, 9 | 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b, 10 | 0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b 11 | }; 12 | 13 | /* Preconditions: a is square or zero */ 14 | 15 | void fe_sqrt(fe out, const fe a) 16 | { 17 | fe exp, b, b2, bi, i; 18 | 19 | fe_frombytes(i, i_bytes); 20 | fe_pow22523(exp, a); /* b = a^(q-5)/8 */ 21 | 22 | /* PRECONDITION: legendre symbol == 1 (square) or 0 (a == zero) */ 23 | #ifndef NDEBUG 24 | fe legendre, zero, one; 25 | 26 | fe_sq(legendre, exp); /* in^((q-5)/4) */ 27 | fe_sq(legendre, legendre); /* in^((q-5)/2) */ 28 | fe_mul(legendre, legendre, a); /* in^((q-3)/2) */ 29 | fe_mul(legendre, legendre, a); /* in^((q-1)/2) */ 30 | 31 | fe_0(zero); 32 | fe_1(one); 33 | assert(fe_isequal(legendre, zero) || fe_isequal(legendre, one)); 34 | #endif 35 | 36 | fe_mul(b, a, exp); /* b = a * a^(q-5)/8 */ 37 | fe_sq(b2, b); /* b^2 = a * a^(q-1)/4 */ 38 | 39 | /* note b^4 == a^2, so b^2 == a or -a 40 | * if b^2 != a, multiply it by sqrt(-1) */ 41 | fe_mul(bi, b, i); 42 | fe_cmov(b, bi, 1 ^ fe_isequal(b2, a)); 43 | fe_copy(out, b); 44 | 45 | /* PRECONDITION: out^2 == a */ 46 | #ifndef NDEBUG 47 | fe_sq(b2, out); 48 | assert(fe_isequal(a, b2)); 49 | #endif 50 | } 51 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/ge_is_small_order.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | #include "utility.h" 4 | #include "stdio.h" 5 | 6 | /* 7 | return 1 if f == g 8 | return 0 if f != g 9 | */ 10 | 11 | int ge_is_small_order(const ge_p3 *p) 12 | { 13 | ge_p1p1 p1p1; 14 | ge_p2 p2; 15 | fe zero; 16 | 17 | ge_p3_dbl(&p1p1, p); 18 | ge_p1p1_to_p2(&p2, &p1p1); 19 | 20 | ge_p2_dbl(&p1p1, &p2); 21 | ge_p1p1_to_p2(&p2, &p1p1); 22 | 23 | ge_p2_dbl(&p1p1, &p2); 24 | ge_p1p1_to_p2(&p2, &p1p1); 25 | 26 | fe_0(zero); 27 | 28 | /* Check if 8*p == neutral element == (0, 1) */ 29 | return (fe_isequal(p2.X, zero) & fe_isequal(p2.Y, p2.Z)); 30 | } 31 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/ge_isneutral.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return 1 if p is the neutral point 6 | return 0 otherwise 7 | */ 8 | 9 | int ge_isneutral(const ge_p3 *p) 10 | { 11 | fe zero; 12 | fe_0(zero); 13 | 14 | /* Check if p == neutral element == (0, 1) */ 15 | return (fe_isequal(p->X, zero) & fe_isequal(p->Y, p->Z)); 16 | } 17 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/ge_montx_to_p2.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "ge.h" 3 | #include "assert.h" 4 | #include "crypto_additions.h" 5 | #include "utility.h" 6 | 7 | /* sqrt(-(A+2)) */ 8 | static unsigned char A_bytes[32] = { 9 | 0x06, 0x7e, 0x45, 0xff, 0xaa, 0x04, 0x6e, 0xcc, 10 | 0x82, 0x1a, 0x7d, 0x4b, 0xd1, 0xd3, 0xa1, 0xc5, 11 | 0x7e, 0x4f, 0xfc, 0x03, 0xdc, 0x08, 0x7b, 0xd2, 12 | 0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f 13 | }; 14 | 15 | void ge_montx_to_p2(ge_p2* p, const fe u, const unsigned char ed_sign_bit) 16 | { 17 | fe x, y, A, v, v2, iv, nx; 18 | 19 | fe_frombytes(A, A_bytes); 20 | 21 | /* given u, recover edwards y */ 22 | /* given u, recover v */ 23 | /* given u and v, recover edwards x */ 24 | 25 | fe_montx_to_edy(y, u); /* y = (u - 1) / (u + 1) */ 26 | 27 | fe_mont_rhs(v2, u); /* v^2 = u(u^2 + Au + 1) */ 28 | fe_sqrt(v, v2); /* v = sqrt(v^2) */ 29 | 30 | fe_mul(x, u, A); /* x = u * sqrt(-(A+2)) */ 31 | fe_invert(iv, v); /* 1/v */ 32 | fe_mul(x, x, iv); /* x = (u/v) * sqrt(-(A+2)) */ 33 | 34 | fe_neg(nx, x); /* negate x to match sign bit */ 35 | fe_cmov(x, nx, fe_isnegative(x) ^ ed_sign_bit); 36 | 37 | fe_copy(p->X, x); 38 | fe_copy(p->Y, y); 39 | fe_1(p->Z); 40 | 41 | /* POSTCONDITION: check that p->X and p->Y satisfy the Ed curve equation */ 42 | /* -x^2 + y^2 = 1 + dx^2y^2 */ 43 | #ifndef NDEBUG 44 | { 45 | fe one, d, x2, y2, x2y2, dx2y2; 46 | 47 | unsigned char dbytes[32] = { 48 | 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 49 | 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, 50 | 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, 51 | 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 52 | }; 53 | 54 | fe_frombytes(d, dbytes); 55 | fe_1(one); 56 | fe_sq(x2, p->X); /* x^2 */ 57 | fe_sq(y2, p->Y); /* y^2 */ 58 | 59 | fe_mul(dx2y2, x2, y2); /* x^2y^2 */ 60 | fe_mul(dx2y2, dx2y2, d); /* dx^2y^2 */ 61 | fe_add(dx2y2, dx2y2, one); /* dx^2y^2 + 1 */ 62 | 63 | fe_neg(x2y2, x2); /* -x^2 */ 64 | fe_add(x2y2, x2y2, y2); /* -x^2 + y^2 */ 65 | 66 | assert(fe_isequal(x2y2, dx2y2)); 67 | } 68 | #endif 69 | } 70 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/ge_montx_to_p3.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "ge.h" 3 | #include "assert.h" 4 | #include "crypto_additions.h" 5 | #include "utility.h" 6 | 7 | /* sqrt(-(A+2)) */ 8 | static unsigned char A_bytes[32] = { 9 | 0x06, 0x7e, 0x45, 0xff, 0xaa, 0x04, 0x6e, 0xcc, 10 | 0x82, 0x1a, 0x7d, 0x4b, 0xd1, 0xd3, 0xa1, 0xc5, 11 | 0x7e, 0x4f, 0xfc, 0x03, 0xdc, 0x08, 0x7b, 0xd2, 12 | 0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f 13 | }; 14 | 15 | void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit) 16 | { 17 | fe x, y, A, v, v2, iv, nx; 18 | 19 | fe_frombytes(A, A_bytes); 20 | 21 | /* given u, recover edwards y */ 22 | /* given u, recover v */ 23 | /* given u and v, recover edwards x */ 24 | 25 | fe_montx_to_edy(y, u); /* y = (u - 1) / (u + 1) */ 26 | 27 | fe_mont_rhs(v2, u); /* v^2 = u(u^2 + Au + 1) */ 28 | fe_sqrt(v, v2); /* v = sqrt(v^2) */ 29 | 30 | fe_mul(x, u, A); /* x = u * sqrt(-(A+2)) */ 31 | fe_invert(iv, v); /* 1/v */ 32 | fe_mul(x, x, iv); /* x = (u/v) * sqrt(-(A+2)) */ 33 | 34 | fe_neg(nx, x); /* negate x to match sign bit */ 35 | fe_cmov(x, nx, fe_isnegative(x) ^ ed_sign_bit); 36 | 37 | fe_copy(p->X, x); 38 | fe_copy(p->Y, y); 39 | fe_1(p->Z); 40 | fe_mul(p->T, p->X, p->Y); 41 | 42 | /* POSTCONDITION: check that p->X and p->Y satisfy the Ed curve equation */ 43 | /* -x^2 + y^2 = 1 + dx^2y^2 */ 44 | #ifndef NDEBUG 45 | { 46 | fe one, d, x2, y2, x2y2, dx2y2; 47 | 48 | unsigned char dbytes[32] = { 49 | 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 50 | 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, 51 | 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, 52 | 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 53 | }; 54 | 55 | fe_frombytes(d, dbytes); 56 | fe_1(one); 57 | fe_sq(x2, p->X); /* x^2 */ 58 | fe_sq(y2, p->Y); /* y^2 */ 59 | 60 | fe_mul(dx2y2, x2, y2); /* x^2y^2 */ 61 | fe_mul(dx2y2, dx2y2, d); /* dx^2y^2 */ 62 | fe_add(dx2y2, dx2y2, one); /* dx^2y^2 + 1 */ 63 | 64 | fe_neg(x2y2, x2); /* -x^2 */ 65 | fe_add(x2y2, x2y2, y2); /* -x^2 + y^2 */ 66 | 67 | assert(fe_isequal(x2y2, dx2y2)); 68 | } 69 | #endif 70 | } 71 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/ge_neg.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return r = -p 6 | */ 7 | 8 | 9 | void ge_neg(ge_p3* r, const ge_p3 *p) 10 | { 11 | fe_neg(r->X, p->X); 12 | fe_copy(r->Y, p->Y); 13 | fe_copy(r->Z, p->Z); 14 | fe_neg(r->T, p->T); 15 | } 16 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/ge_p3_to_montx.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_additions.h" 3 | 4 | void ge_p3_to_montx(fe u, const ge_p3 *ed) 5 | { 6 | /* 7 | u = (y + 1) / (1 - y) 8 | or 9 | u = (y + z) / (z - y) 10 | 11 | NOTE: y=1 is converted to u=0 since fe_invert is mod-exp 12 | */ 13 | 14 | fe y_plus_one, one_minus_y, inv_one_minus_y; 15 | 16 | fe_add(y_plus_one, ed->Y, ed->Z); 17 | fe_sub(one_minus_y, ed->Z, ed->Y); 18 | fe_invert(inv_one_minus_y, one_minus_y); 19 | fe_mul(u, y_plus_one, inv_one_minus_y); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/ge_scalarmult.c: -------------------------------------------------------------------------------- 1 | #include "crypto_uint32.h" 2 | #include "ge.h" 3 | #include "crypto_additions.h" 4 | 5 | static unsigned char equal(signed char b,signed char c) 6 | { 7 | unsigned char ub = b; 8 | unsigned char uc = c; 9 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 10 | crypto_uint32 y = x; /* 0: yes; 1..255: no */ 11 | y -= 1; /* 4294967295: yes; 0..254: no */ 12 | y >>= 31; /* 1: yes; 0: no */ 13 | return y; 14 | } 15 | 16 | static unsigned char negative(signed char b) 17 | { 18 | unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 19 | x >>= 63; /* 1: yes; 0: no */ 20 | return x; 21 | } 22 | 23 | static void cmov(ge_cached *t,const ge_cached *u,unsigned char b) 24 | { 25 | fe_cmov(t->YplusX,u->YplusX,b); 26 | fe_cmov(t->YminusX,u->YminusX,b); 27 | fe_cmov(t->Z,u->Z,b); 28 | fe_cmov(t->T2d,u->T2d,b); 29 | } 30 | 31 | static void select(ge_cached *t,const ge_cached *pre, signed char b) 32 | { 33 | ge_cached minust; 34 | unsigned char bnegative = negative(b); 35 | unsigned char babs = b - (((-bnegative) & b) << 1); 36 | 37 | fe_1(t->YplusX); 38 | fe_1(t->YminusX); 39 | fe_1(t->Z); 40 | fe_0(t->T2d); 41 | 42 | cmov(t,pre+0,equal(babs,1)); 43 | cmov(t,pre+1,equal(babs,2)); 44 | cmov(t,pre+2,equal(babs,3)); 45 | cmov(t,pre+3,equal(babs,4)); 46 | cmov(t,pre+4,equal(babs,5)); 47 | cmov(t,pre+5,equal(babs,6)); 48 | cmov(t,pre+6,equal(babs,7)); 49 | cmov(t,pre+7,equal(babs,8)); 50 | fe_copy(minust.YplusX,t->YminusX); 51 | fe_copy(minust.YminusX,t->YplusX); 52 | fe_copy(minust.Z,t->Z); 53 | fe_neg(minust.T2d,t->T2d); 54 | cmov(t,&minust,bnegative); 55 | } 56 | 57 | /* 58 | h = a * B 59 | where a = a[0]+256*a[1]+...+256^31 a[31] 60 | B is the Ed25519 base point (x,4/5) with x positive. 61 | 62 | Preconditions: 63 | a[31] <= 127 64 | */ 65 | 66 | void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A) 67 | { 68 | signed char e[64]; 69 | signed char carry; 70 | ge_p1p1 r; 71 | ge_p2 s; 72 | ge_p3 t0, t1, t2; 73 | ge_cached t, pre[8]; 74 | int i; 75 | 76 | for (i = 0;i < 32;++i) { 77 | e[2 * i + 0] = (a[i] >> 0) & 15; 78 | e[2 * i + 1] = (a[i] >> 4) & 15; 79 | } 80 | /* each e[i] is between 0 and 15 */ 81 | /* e[63] is between 0 and 7 */ 82 | 83 | carry = 0; 84 | for (i = 0;i < 63;++i) { 85 | e[i] += carry; 86 | carry = e[i] + 8; 87 | carry >>= 4; 88 | e[i] -= carry << 4; 89 | } 90 | e[63] += carry; 91 | /* each e[i] is between -8 and 8 */ 92 | 93 | // Precomputation: 94 | ge_p3_to_cached(pre+0, A); // A 95 | 96 | ge_p3_dbl(&r, A); 97 | ge_p1p1_to_p3(&t0, &r); 98 | ge_p3_to_cached(pre+1, &t0); // 2A 99 | 100 | ge_add(&r, A, pre+1); 101 | ge_p1p1_to_p3(&t1, &r); 102 | ge_p3_to_cached(pre+2, &t1); // 3A 103 | 104 | ge_p3_dbl(&r, &t0); 105 | ge_p1p1_to_p3(&t0, &r); 106 | ge_p3_to_cached(pre+3, &t0); // 4A 107 | 108 | ge_add(&r, A, pre+3); 109 | ge_p1p1_to_p3(&t2, &r); 110 | ge_p3_to_cached(pre+4, &t2); // 5A 111 | 112 | ge_p3_dbl(&r, &t1); 113 | ge_p1p1_to_p3(&t1, &r); 114 | ge_p3_to_cached(pre+5, &t1); // 6A 115 | 116 | ge_add(&r, A, pre+5); 117 | ge_p1p1_to_p3(&t1, &r); 118 | ge_p3_to_cached(pre+6, &t1); // 7A 119 | 120 | ge_p3_dbl(&r, &t0); 121 | ge_p1p1_to_p3(&t0, &r); 122 | ge_p3_to_cached(pre+7, &t0); // 8A 123 | 124 | ge_p3_0(h); 125 | 126 | for (i = 63;i > 0; i--) { 127 | select(&t,pre,e[i]); 128 | ge_add(&r, h, &t); 129 | ge_p1p1_to_p2(&s,&r); 130 | 131 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 132 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 133 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 134 | ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); 135 | 136 | } 137 | select(&t,pre,e[0]); 138 | ge_add(&r, h, &t); 139 | ge_p1p1_to_p3(h,&r); 140 | } 141 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/ge_scalarmult_cofactor.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return 8 * p 6 | */ 7 | 8 | void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p) 9 | { 10 | ge_p1p1 p1p1; 11 | ge_p2 p2; 12 | 13 | ge_p3_dbl(&p1p1, p); 14 | ge_p1p1_to_p2(&p2, &p1p1); 15 | 16 | ge_p2_dbl(&p1p1, &p2); 17 | ge_p1p1_to_p2(&p2, &p1p1); 18 | 19 | ge_p2_dbl(&p1p1, &p2); 20 | ge_p1p1_to_p3(q, &p1p1); 21 | } 22 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/keygen.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | #include "keygen.h" 3 | #include "crypto_additions.h" 4 | 5 | void curve25519_keygen(unsigned char* curve25519_pubkey_out, 6 | const unsigned char* curve25519_privkey_in) 7 | { 8 | /* Perform a fixed-base multiplication of the Edwards base point, 9 | (which is efficient due to precalculated tables), then convert 10 | to the Curve25519 montgomery-format public key. 11 | 12 | NOTE: y=1 is converted to u=0 since fe_invert is mod-exp 13 | */ 14 | 15 | ge_p3 ed; /* Ed25519 pubkey point */ 16 | fe u; 17 | 18 | ge_scalarmult_base(&ed, curve25519_privkey_in); 19 | ge_p3_to_montx(u, &ed); 20 | fe_tobytes(curve25519_pubkey_out, u); 21 | } 22 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/keygen.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __KEYGEN_H__ 3 | #define __KEYGEN_H__ 4 | 5 | /* Sets and clears bits to make a random 32 bytes into a private key */ 6 | void sc_clamp(unsigned char* a); 7 | 8 | /* The private key should be 32 random bytes "clamped" by sc_clamp() */ 9 | void curve25519_keygen(unsigned char* curve25519_pubkey_out, /* 32 bytes */ 10 | const unsigned char* curve25519_privkey_in); /* 32 bytes */ 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/open_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "crypto_verify_32.h" 5 | #include "ge.h" 6 | #include "sc.h" 7 | #include "crypto_additions.h" 8 | 9 | int crypto_sign_open_modified( 10 | unsigned char *m, 11 | const unsigned char *sm,unsigned long long smlen, 12 | const unsigned char *pk 13 | ) 14 | { 15 | unsigned char pkcopy[32]; 16 | unsigned char rcopy[32]; 17 | unsigned char scopy[32]; 18 | unsigned char h[64]; 19 | unsigned char rcheck[32]; 20 | ge_p3 A; 21 | ge_p2 R; 22 | 23 | if (smlen < 64) goto badsig; 24 | if (sm[63] & 224) goto badsig; /* strict parsing of s */ 25 | if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; 26 | 27 | memmove(pkcopy,pk,32); 28 | memmove(rcopy,sm,32); 29 | memmove(scopy,sm + 32,32); 30 | 31 | memmove(m,sm,smlen); 32 | memmove(m + 32,pkcopy,32); 33 | crypto_hash_sha512(h,m,smlen); 34 | sc_reduce(h); 35 | 36 | ge_double_scalarmult_vartime(&R,h,&A,scopy); 37 | ge_tobytes(rcheck,&R); 38 | 39 | if (crypto_verify_32(rcheck,rcopy) == 0) { 40 | return 0; 41 | } 42 | 43 | badsig: 44 | return -1; 45 | } 46 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/sc_clamp.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | 3 | void sc_clamp(unsigned char* a) 4 | { 5 | a[0] &= 248; 6 | a[31] &= 127; 7 | a[31] |= 64; 8 | } 9 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/sc_cmov.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | 3 | /* 4 | Replace (f,g) with (g,g) if b == 1; 5 | replace (f,g) with (f,g) if b == 0. 6 | 7 | Preconditions: b in {0,1}. 8 | */ 9 | 10 | void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b) 11 | { 12 | int count=32; 13 | unsigned char x[32]; 14 | for (count=0; count < 32; count++) 15 | x[count] = f[count] ^ g[count]; 16 | b = -b; 17 | for (count=0; count < 32; count++) 18 | x[count] &= b; 19 | for (count=0; count < 32; count++) 20 | f[count] = f[count] ^ x[count]; 21 | } 22 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/sc_neg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_additions.h" 3 | #include "sc.h" 4 | 5 | /* l = order of base point = 2^252 + 27742317777372353535851937790883648493 */ 6 | 7 | /* 8 | static unsigned char l[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 9 | 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x10}; 12 | */ 13 | 14 | static unsigned char lminus1[32] = {0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 15 | 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 18 | 19 | /* b = -a (mod l) */ 20 | void sc_neg(unsigned char *b, const unsigned char *a) 21 | { 22 | unsigned char zero[32]; 23 | memset(zero, 0, 32); 24 | sc_muladd(b, lminus1, a, zero); /* b = (-1)a + 0 (mod l) */ 25 | } 26 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/sign_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "ge.h" 5 | #include "sc.h" 6 | #include "zeroize.h" 7 | #include "crypto_additions.h" 8 | 9 | /* NEW: Compare to pristine crypto_sign() 10 | Uses explicit private key for nonce derivation and as scalar, 11 | instead of deriving both from a master key. 12 | */ 13 | int crypto_sign_modified( 14 | unsigned char *sm, 15 | const unsigned char *m,unsigned long long mlen, 16 | const unsigned char *sk, const unsigned char* pk, 17 | const unsigned char* random 18 | ) 19 | { 20 | unsigned char nonce[64]; 21 | unsigned char hram[64]; 22 | ge_p3 R; 23 | int count=0; 24 | 25 | memmove(sm + 64,m,mlen); 26 | memmove(sm + 32,sk,32); /* NEW: Use privkey directly for nonce derivation */ 27 | 28 | /* NEW : add prefix to separate hash uses - see .h */ 29 | sm[0] = 0xFE; 30 | for (count = 1; count < 32; count++) 31 | sm[count] = 0xFF; 32 | 33 | /* NEW: add suffix of random data */ 34 | memmove(sm + mlen + 64, random, 64); 35 | 36 | crypto_hash_sha512(nonce,sm,mlen + 128); 37 | memmove(sm + 32,pk,32); 38 | 39 | sc_reduce(nonce); 40 | 41 | ge_scalarmult_base(&R,nonce); 42 | ge_p3_tobytes(sm,&R); 43 | 44 | crypto_hash_sha512(hram,sm,mlen + 64); 45 | sc_reduce(hram); 46 | sc_muladd(sm + 32,hram,sk,nonce); /* NEW: Use privkey directly */ 47 | 48 | /* Erase any traces of private scalar or 49 | nonce left in the stack from sc_muladd */ 50 | zeroize_stack(); 51 | zeroize(nonce, 64); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/uopen_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sc.h" 3 | #include "ge.h" 4 | #include "crypto_hash_sha512.h" 5 | #include "crypto_verify_32.h" 6 | #include "crypto_additions.h" 7 | #include "crypto_sign.h" 8 | 9 | int crypto_usign_open_modified( 10 | unsigned char *m,unsigned long long *mlen, 11 | const unsigned char *sm,unsigned long long smlen, 12 | const unsigned char *pk, const ge_p3* Bu 13 | ) 14 | { 15 | ge_p3 U; 16 | unsigned char h[64]; 17 | unsigned char s[64]; 18 | unsigned char strict[64]; 19 | ge_p3 A; 20 | ge_p2 R; 21 | unsigned char hcheck[64]; 22 | int count; 23 | 24 | if (smlen < 96) goto badsig; 25 | if (sm[63] & 224) goto badsig; /* strict parsing of h */ 26 | if (sm[95] & 224) goto badsig; /* strict parsing of s */ 27 | 28 | /* Load -A */ 29 | if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; 30 | 31 | /* Load -U, h, s */ 32 | ge_frombytes_negate_vartime(&U, sm); 33 | memset(h, 0, 64); 34 | memset(s, 0, 64); 35 | memmove(h, sm + 32, 32); 36 | memmove(s, sm + 64, 32); 37 | 38 | /* Insist that s and h are reduced scalars (strict parsing) */ 39 | memcpy(strict, h, 64); 40 | sc_reduce(strict); 41 | if (memcmp(strict, h, 32) != 0) 42 | goto badsig; 43 | memcpy(strict, s, 64); 44 | sc_reduce(strict); 45 | if (memcmp(strict, s, 32) != 0) 46 | goto badsig; 47 | 48 | /* Reject U (actually -U) if small order */ 49 | if (ge_is_small_order(&U)) 50 | goto badsig; 51 | 52 | // R = sB + h(-A) 53 | ge_double_scalarmult_vartime(&R,h,&A,s); 54 | 55 | // Ru = sBu + h(-U) 56 | ge_p3 sBu, hU; 57 | 58 | // sBu 59 | ge_scalarmult(&sBu, s, Bu); 60 | 61 | // h(-U) 62 | ge_scalarmult(&hU, h, &U); 63 | 64 | // Ru = sBu + h(-U) 65 | ge_p1p1 Rp1p1; 66 | ge_p3 Ru; 67 | ge_cached hUcached; 68 | ge_p3_to_cached(&hUcached, &hU); 69 | ge_add(&Rp1p1, &sBu, &hUcached); 70 | ge_p1p1_to_p3(&Ru, &Rp1p1); 71 | 72 | 73 | // Check h == SHA512(label(4) || A || U || R || Ru || M) 74 | m[0] = 0xFB; 75 | for (count = 1; count < 32; count++) 76 | m[count] = 0xFF; 77 | memmove(m+32, pk, 32); 78 | /* undo the negation for U */ 79 | fe_neg(U.X, U.X); 80 | fe_neg(U.T, U.T); 81 | ge_p3_tobytes(m+64, &U); 82 | ge_tobytes(m+96, &R); 83 | ge_p3_tobytes(m+128, &Ru); 84 | memmove(m+160, sm+96, smlen - 96); 85 | 86 | crypto_hash_sha512(hcheck, m, smlen + 64); 87 | sc_reduce(hcheck); 88 | 89 | if (crypto_verify_32(hcheck, h) == 0) { 90 | memmove(m,m + 64,smlen - 64); 91 | memset(m + smlen - 64,0,64); 92 | *mlen = smlen - 64; 93 | return 0; 94 | } 95 | 96 | badsig: 97 | *mlen = -1; 98 | memset(m,0,smlen); 99 | return -1; 100 | } 101 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/usign_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "ge.h" 5 | #include "sc.h" 6 | #include "zeroize.h" 7 | #include "crypto_additions.h" 8 | 9 | /* NEW: Compare to pristine crypto_sign() 10 | Uses explicit private key for nonce derivation and as scalar, 11 | instead of deriving both from a master key. 12 | */ 13 | int crypto_usign_modified( 14 | unsigned char *sm, 15 | const unsigned char *M,unsigned long Mlen, 16 | const unsigned char *a, 17 | const unsigned char *A, 18 | const unsigned char *random, 19 | const ge_p3 *Bu, 20 | const unsigned char *U 21 | ) 22 | { 23 | unsigned char r[64]; 24 | unsigned char h[64]; 25 | ge_p3 R, Ru; 26 | int count=0; 27 | 28 | /* r = SHA512(label(3) || a || U || random(64)) */ 29 | sm[0] = 0xFC; 30 | for (count = 1; count < 32; count++) 31 | sm[count] = 0xFF; 32 | 33 | memmove(sm + 32, a, 32); /* Use privkey directly for nonce derivation */ 34 | memmove(sm + 64, U, 32); 35 | 36 | memmove(sm + 96, random, 64); /* Add suffix of random data */ 37 | crypto_hash_sha512(r, sm, 160); 38 | 39 | sc_reduce(r); 40 | ge_scalarmult_base(&R, r); 41 | ge_scalarmult(&Ru, r, Bu); 42 | 43 | /* h = SHA512(label(4) || A || U || R || Ru || M) */ 44 | sm[0] = 0xFB; 45 | memmove(sm + 32, A, 32); 46 | memmove(sm + 64, U, 32); 47 | ge_p3_tobytes(sm+96, &R); 48 | ge_p3_tobytes(sm+128, &Ru); 49 | memmove(sm + 160, M, Mlen); 50 | 51 | crypto_hash_sha512(h, sm, Mlen + 160); 52 | sc_reduce(h); 53 | 54 | memmove(sm, h, 32); /* Write h */ 55 | sc_muladd(sm + 32, h, a, r); /* Write s */ 56 | 57 | /* Erase any traces of private scalar or 58 | nonce left in the stack from sc_muladd. */ 59 | zeroize_stack(); 60 | zeroize(r, 64); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/utility.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | 5 | void print_vector(const char* name, const unsigned char* v) 6 | { 7 | int count; 8 | printf("%s = \n", name); 9 | for (count = 0; count < 32; count++) 10 | printf("%02x ", v[count]); 11 | printf("\n"); 12 | } 13 | 14 | void print_bytes(const char* name, const unsigned char* v, int numbytes) 15 | { 16 | int count; 17 | printf("%s = \n", name); 18 | for (count = 0; count < numbytes; count++) 19 | printf("%02x ", v[count]); 20 | printf("\n"); 21 | } 22 | 23 | void print_fe(const char* name, const fe in) 24 | { 25 | unsigned char bytes[32]; 26 | fe_tobytes(bytes, in); 27 | print_vector(name, bytes); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/utility.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __UTILITY_H__ 3 | #define __UTILITY_H__ 4 | 5 | #include "fe.h" 6 | 7 | void print_vector(const char* name, const unsigned char* v); 8 | void print_bytes(const char* name, const unsigned char* v, int numbytes); 9 | void print_fe(const char* name, const fe in); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/vopen_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sc.h" 3 | #include "ge.h" 4 | #include "crypto_hash_sha512.h" 5 | #include "crypto_verify_32.h" 6 | #include "crypto_additions.h" 7 | #include "crypto_sign.h" 8 | 9 | int crypto_vsign_open_modified( 10 | unsigned char *m, 11 | const unsigned char *sm,unsigned long long smlen, 12 | const unsigned char *pk, const ge_p3* Bv 13 | ) 14 | { 15 | ge_p3 Vneg, V, Aneg, A, c_V, c_A, h_Vneg, s_Bv; 16 | unsigned char h[32]; 17 | unsigned char s[32]; 18 | ge_p2 R; 19 | unsigned char hcheck[64]; 20 | unsigned char vrf_output[64]; 21 | int count; 22 | 23 | if (smlen < 96) goto badsig; 24 | if (sm[63] & 224) goto badsig; /* strict parsing of h */ 25 | if (sm[95] & 224) goto badsig; /* strict parsing of s */ 26 | 27 | /* Load -A */ 28 | if (ge_frombytes_negate_vartime(&Aneg,pk) != 0) goto badsig; 29 | 30 | /* Load -V, h, s */ 31 | if (ge_frombytes_negate_vartime(&Vneg, sm) != 0) goto badsig; 32 | memmove(h, sm + 32, 32); 33 | memmove(s, sm + 64, 32); 34 | if (h[31] & 224) goto badsig; /* strict parsing of h */ 35 | if (s[31] & 224) goto badsig; /* strict parsing of s */ 36 | 37 | ge_neg(&A, &Aneg); 38 | ge_neg(&V, &Vneg); 39 | ge_scalarmult_cofactor(&c_A, &A); 40 | ge_scalarmult_cofactor(&c_V, &V); 41 | if (ge_isneutral(&c_A) || ge_isneutral(&c_V) || ge_isneutral(Bv)) 42 | goto badsig; 43 | 44 | // R = (s*B) + (h * -A)) 45 | ge_double_scalarmult_vartime(&R, h, &Aneg, s); 46 | 47 | // s * Bv 48 | ge_scalarmult(&s_Bv, s, Bv); 49 | 50 | // h * -V 51 | ge_scalarmult(&h_Vneg, h, &Vneg); 52 | 53 | // Rv = (sc * Bv) + (hc * (-V)) 54 | ge_p1p1 Rp1p1; 55 | ge_p3 Rv; 56 | ge_cached h_Vnegcached; 57 | ge_p3_to_cached(&h_Vnegcached, &h_Vneg); 58 | ge_add(&Rp1p1, &s_Bv, &h_Vnegcached); 59 | ge_p1p1_to_p3(&Rv, &Rp1p1); 60 | 61 | // Check h == SHA512(label(4) || A || V || R || Rv || M) 62 | m[0] = 0xFB; // label 4 63 | for (count = 1; count < 32; count++) 64 | m[count] = 0xFF; 65 | memmove(m+32, pk, 32); 66 | ge_p3_tobytes(m+64, &V); 67 | ge_tobytes(m+96, &R); 68 | ge_p3_tobytes(m+128, &Rv); 69 | memmove(m+160, sm+96, smlen - 96); 70 | 71 | crypto_hash_sha512(hcheck, m, smlen + 64); 72 | sc_reduce(hcheck); 73 | 74 | if (crypto_verify_32(hcheck, h) == 0) { 75 | ge_p3_tobytes(m+32, &c_V); 76 | m[0] = 0xFA; // label 5 77 | crypto_hash_sha512(vrf_output, m, 64); 78 | memmove(m, vrf_output, 32); 79 | return 0; 80 | } 81 | 82 | badsig: 83 | memset(m, 0, 32); 84 | return -1; 85 | } 86 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/vsign_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "ge.h" 5 | #include "sc.h" 6 | #include "zeroize.h" 7 | #include "crypto_additions.h" 8 | 9 | /* NEW: Compare to pristine crypto_sign() 10 | Uses explicit private key for nonce derivation and as scalar, 11 | instead of deriving both from a master key. 12 | */ 13 | int crypto_vsign_modified( 14 | unsigned char *sm, 15 | const unsigned char *M,unsigned long Mlen, 16 | const unsigned char *a, 17 | const unsigned char *A, 18 | const unsigned char *random, 19 | const ge_p3 *Bv, 20 | const unsigned char *V 21 | ) 22 | { 23 | unsigned char r[64]; 24 | unsigned char h[64]; 25 | ge_p3 R, Rv; 26 | int count=0; 27 | 28 | /* r = SHA512(label(3) || a || V || random(64)) */ 29 | sm[0] = 0xFC; 30 | for (count = 1; count < 32; count++) 31 | sm[count] = 0xFF; 32 | 33 | memmove(sm + 32, a, 32); /* Use privkey directly for nonce derivation */ 34 | memmove(sm + 64, V, 32); 35 | 36 | memmove(sm + 96, random, 64); /* Add suffix of random data */ 37 | crypto_hash_sha512(r, sm, 160); 38 | 39 | sc_reduce(r); 40 | ge_scalarmult_base(&R, r); 41 | ge_scalarmult(&Rv, r, Bv); 42 | 43 | /* h = SHA512(label(4) || A || V || R || Rv || M) */ 44 | sm[0] = 0xFB; 45 | memmove(sm + 32, A, 32); 46 | memmove(sm + 64, V, 32); 47 | ge_p3_tobytes(sm+96, &R); 48 | ge_p3_tobytes(sm+128, &Rv); 49 | memmove(sm + 160, M, Mlen); 50 | 51 | crypto_hash_sha512(h, sm, Mlen + 160); 52 | sc_reduce(h); 53 | 54 | memmove(sm, h, 32); /* Write h */ 55 | sc_muladd(sm + 32, h, a, r); /* Write s */ 56 | 57 | /* Erase any traces of private scalar or 58 | nonce left in the stack from sc_muladd. */ 59 | zeroize_stack(); 60 | zeroize(r, 64); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/vxeddsa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ge.h" 3 | #include "crypto_additions.h" 4 | #include "zeroize.h" 5 | #include "vxeddsa.h" 6 | #include "crypto_verify_32.h" 7 | 8 | int vxed25519_sign(unsigned char* signature_out, 9 | const unsigned char* curve25519_privkey, 10 | const unsigned char* msg, const unsigned long msg_len, 11 | const unsigned char* random) 12 | { 13 | unsigned char a[32], aneg[32]; 14 | unsigned char A[32]; 15 | ge_p3 Bv, ed_pubkey_point; 16 | unsigned char sigbuf[MAX_MSG_LEN + 160]; /* working buffer */ 17 | unsigned char sign_bit = 0; 18 | 19 | if (msg_len > MAX_MSG_LEN) { 20 | memset(signature_out, 0, 96); 21 | return -1; 22 | } 23 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 24 | ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); 25 | ge_p3_tobytes(A, &ed_pubkey_point); 26 | 27 | /* Force Edwards sign bit to zero */ 28 | sign_bit = (A[31] & 0x80) >> 7; 29 | memcpy(a, curve25519_privkey, 32); 30 | sc_neg(aneg, a); 31 | sc_cmov(a, aneg, sign_bit); 32 | A[31] &= 0x7F; 33 | 34 | calculate_Bv_and_V(&Bv, signature_out, sigbuf, a, A, msg, msg_len); 35 | 36 | /* Perform an Ed25519 signature with explicit private key */ 37 | crypto_vsign_modified(sigbuf, msg, msg_len, a, A, random, &Bv, signature_out /*V*/); 38 | memmove(signature_out+32, sigbuf, 64); 39 | 40 | zeroize(a, 32); 41 | zeroize(aneg, 32); 42 | return 0; 43 | } 44 | 45 | int vxed25519_verify(unsigned char* vrf_out, 46 | const unsigned char* signature, 47 | const unsigned char* curve25519_pubkey, 48 | const unsigned char* msg, const unsigned long msg_len) 49 | { 50 | fe u; 51 | fe y; 52 | unsigned char ed_pubkey[32]; 53 | unsigned char strict[32]; 54 | unsigned char verifybuf[MAX_MSG_LEN + 160]; /* working buffer */ 55 | unsigned char verifybuf2[MAX_MSG_LEN + 160]; /* working buffer #2 ?? !!! */ 56 | ge_p3 Bv; 57 | 58 | if (msg_len > MAX_MSG_LEN) { 59 | return -1; 60 | } 61 | 62 | /* Convert the Curve25519 public key (u) into an Ed25519 public key. 63 | 64 | y = (u - 1) / (u + 1) 65 | 66 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 67 | */ 68 | fe_frombytes(u, curve25519_pubkey); 69 | fe_tobytes(strict, u); 70 | if (crypto_verify_32(strict, curve25519_pubkey) != 0) 71 | return 0; 72 | fe_montx_to_edy(y, u); 73 | fe_tobytes(ed_pubkey, y); 74 | 75 | calculate_Bv(&Bv, verifybuf, ed_pubkey, msg, msg_len); 76 | 77 | memmove(verifybuf, signature, 96); 78 | memmove(verifybuf+96, msg, msg_len); 79 | 80 | /* Then perform a signature verification, return 0 on success */ 81 | /* The below call has a strange API: */ 82 | /* verifybuf = V || h || s || message */ 83 | /* verifybuf2 = used as buffer, gets the VRF output if success */ 84 | if (crypto_vsign_open_modified(verifybuf2, verifybuf, 96 + msg_len, ed_pubkey, &Bv) == 0) { 85 | memmove(vrf_out, verifybuf2, 32); 86 | return 0; 87 | } else { 88 | memset(vrf_out, 0, 32); 89 | return -1; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/vxeddsa.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __VXEDDSA_H__ 3 | #define __VXEDDSA_H__ 4 | 5 | /* returns 0 on success */ 6 | int vxed25519_sign(unsigned char* signature_out, /* 96 bytes */ 7 | const unsigned char* curve25519_privkey, /* 32 bytes */ 8 | const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ 9 | const unsigned char* random); /* 64 bytes */ 10 | 11 | /* returns 0 on success */ 12 | int vxed25519_verify(unsigned char* vrf_out, /* 32 bytes */ 13 | const unsigned char* signature, /* 96 bytes */ 14 | const unsigned char* curve25519_pubkey, /* 32 bytes */ 15 | const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ 16 | 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/xeddsa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ge.h" 3 | #include "crypto_additions.h" 4 | #include "zeroize.h" 5 | #include "xeddsa.h" 6 | #include "crypto_verify_32.h" 7 | 8 | int xed25519_sign(unsigned char* signature_out, 9 | const unsigned char* curve25519_privkey, 10 | const unsigned char* msg, const unsigned long msg_len, 11 | const unsigned char* random) 12 | { 13 | unsigned char a[32], aneg[32]; 14 | unsigned char A[32]; 15 | ge_p3 ed_pubkey_point; 16 | unsigned char *sigbuf; /* working buffer */ 17 | unsigned char sign_bit = 0; 18 | 19 | if ((sigbuf = malloc(msg_len + 128)) == 0) { 20 | memset(signature_out, 0, 64); 21 | return -1; 22 | } 23 | 24 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 25 | ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); 26 | ge_p3_tobytes(A, &ed_pubkey_point); 27 | 28 | /* Force Edwards sign bit to zero */ 29 | sign_bit = (A[31] & 0x80) >> 7; 30 | memcpy(a, curve25519_privkey, 32); 31 | sc_neg(aneg, a); 32 | sc_cmov(a, aneg, sign_bit); 33 | A[31] &= 0x7F; 34 | 35 | /* Perform an Ed25519 signature with explicit private key */ 36 | crypto_sign_modified(sigbuf, msg, msg_len, a, A, random); 37 | memmove(signature_out, sigbuf, 64); 38 | 39 | zeroize(a, 32); 40 | zeroize(aneg, 32); 41 | free(sigbuf); 42 | return 0; 43 | } 44 | 45 | int xed25519_verify(const unsigned char* signature, 46 | const unsigned char* curve25519_pubkey, 47 | const unsigned char* msg, const unsigned long msg_len) 48 | { 49 | fe u; 50 | fe y; 51 | unsigned char ed_pubkey[32]; 52 | unsigned char strict[32]; 53 | unsigned char verifybuf[MAX_MSG_LEN + 64]; /* working buffer */ 54 | unsigned char verifybuf2[MAX_MSG_LEN + 64]; /* working buffer #2 */ 55 | 56 | if (msg_len > MAX_MSG_LEN) { 57 | return -1; 58 | } 59 | 60 | /* Convert the Curve25519 public key into an Ed25519 public key. 61 | 62 | y = (u - 1) / (u + 1) 63 | 64 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 65 | */ 66 | fe_frombytes(u, curve25519_pubkey); 67 | fe_tobytes(strict, u); 68 | if (crypto_verify_32(strict, curve25519_pubkey) != 0) 69 | return 0; 70 | fe_montx_to_edy(y, u); 71 | fe_tobytes(ed_pubkey, y); 72 | 73 | memmove(verifybuf, signature, 64); 74 | memmove(verifybuf+64, msg, msg_len); 75 | 76 | /* Then perform a normal Ed25519 verification, return 0 on success */ 77 | /* The below call has a strange API: */ 78 | /* verifybuf = R || S || message */ 79 | /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets 80 | replaced with pubkey for hashing */ 81 | return crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); 82 | } 83 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/xeddsa.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __XEDDSA_H__ 3 | #define __XEDDSA_H__ 4 | 5 | /* returns 0 on success */ 6 | int xed25519_sign(unsigned char* signature_out, /* 64 bytes */ 7 | const unsigned char* curve25519_privkey, /* 32 bytes */ 8 | const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ 9 | const unsigned char* random); /* 64 bytes */ 10 | 11 | /* returns 0 on success */ 12 | int xed25519_verify(const unsigned char* signature, /* 64 bytes */ 13 | const unsigned char* curve25519_pubkey, /* 32 bytes */ 14 | const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/zeroize.c: -------------------------------------------------------------------------------- 1 | #include "zeroize.h" 2 | 3 | void zeroize(unsigned char* b, size_t len) 4 | { 5 | size_t count = 0; 6 | volatile unsigned char *p = b; 7 | 8 | for (count = 0; count < len; count++) 9 | p[count] = 0; 10 | } 11 | 12 | void zeroize_stack() 13 | { 14 | unsigned char m[ZEROIZE_STACK_SIZE]; 15 | zeroize(m, ZEROIZE_STACK_SIZE); 16 | } 17 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/additions/zeroize.h: -------------------------------------------------------------------------------- 1 | #ifndef __ZEROIZE_H__ 2 | #define __ZEROIZE_H__ 3 | 4 | #include 5 | 6 | #define ZEROIZE_STACK_SIZE 1024 7 | 8 | void zeroize(unsigned char* b, size_t len); 9 | 10 | void zeroize_stack(); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/base2.h: -------------------------------------------------------------------------------- 1 | { 2 | { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, 3 | { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, 4 | { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, 5 | }, 6 | { 7 | { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, 8 | { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, 9 | { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, 10 | }, 11 | { 12 | { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, 13 | { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, 14 | { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, 15 | }, 16 | { 17 | { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, 18 | { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, 19 | { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, 20 | }, 21 | { 22 | { -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 }, 23 | { -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 }, 24 | { 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 }, 25 | }, 26 | { 27 | { -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 }, 28 | { 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 }, 29 | { 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 }, 30 | }, 31 | { 32 | { -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 }, 33 | { -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 }, 34 | { -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 }, 35 | }, 36 | { 37 | { -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 }, 38 | { -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 }, 39 | { -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 }, 40 | }, 41 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/d.h: -------------------------------------------------------------------------------- 1 | -10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116 2 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/d2.h: -------------------------------------------------------------------------------- 1 | -21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199 2 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe.h: -------------------------------------------------------------------------------- 1 | #ifndef FE_H 2 | #define FE_H 3 | 4 | #include "crypto_int32.h" 5 | 6 | typedef crypto_int32 fe[10]; 7 | 8 | /* 9 | fe means field element. 10 | Here the field is \Z/(2^255-19). 11 | An element t, entries t[0]...t[9], represents the integer 12 | t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. 13 | Bounds on each t[i] vary depending on context. 14 | */ 15 | 16 | #define fe_frombytes crypto_sign_ed25519_ref10_fe_frombytes 17 | #define fe_tobytes crypto_sign_ed25519_ref10_fe_tobytes 18 | #define fe_copy crypto_sign_ed25519_ref10_fe_copy 19 | #define fe_isnonzero crypto_sign_ed25519_ref10_fe_isnonzero 20 | #define fe_isnegative crypto_sign_ed25519_ref10_fe_isnegative 21 | #define fe_0 crypto_sign_ed25519_ref10_fe_0 22 | #define fe_1 crypto_sign_ed25519_ref10_fe_1 23 | #define fe_cswap crypto_sign_ed25519_ref10_fe_cswap 24 | #define fe_cmov crypto_sign_ed25519_ref10_fe_cmov 25 | #define fe_add crypto_sign_ed25519_ref10_fe_add 26 | #define fe_sub crypto_sign_ed25519_ref10_fe_sub 27 | #define fe_neg crypto_sign_ed25519_ref10_fe_neg 28 | #define fe_mul crypto_sign_ed25519_ref10_fe_mul 29 | #define fe_sq crypto_sign_ed25519_ref10_fe_sq 30 | #define fe_sq2 crypto_sign_ed25519_ref10_fe_sq2 31 | #define fe_mul121666 crypto_sign_ed25519_ref10_fe_mul121666 32 | #define fe_invert crypto_sign_ed25519_ref10_fe_invert 33 | #define fe_pow22523 crypto_sign_ed25519_ref10_fe_pow22523 34 | 35 | extern void fe_frombytes(fe,const unsigned char *); 36 | extern void fe_tobytes(unsigned char *,const fe); 37 | 38 | extern void fe_copy(fe,const fe); 39 | extern int fe_isnonzero(const fe); 40 | extern int fe_isnegative(const fe); 41 | extern void fe_0(fe); 42 | extern void fe_1(fe); 43 | extern void fe_cswap(fe,fe,unsigned int); 44 | extern void fe_cmov(fe,const fe,unsigned int); 45 | 46 | extern void fe_add(fe,const fe,const fe); 47 | extern void fe_sub(fe,const fe,const fe); 48 | extern void fe_neg(fe,const fe); 49 | extern void fe_mul(fe,const fe,const fe); 50 | extern void fe_sq(fe,const fe); 51 | extern void fe_sq2(fe,const fe); 52 | extern void fe_mul121666(fe,const fe); 53 | extern void fe_invert(fe,const fe); 54 | extern void fe_pow22523(fe,const fe); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_0.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = 0 5 | */ 6 | 7 | void fe_0(fe h) 8 | { 9 | h[0] = 0; 10 | h[1] = 0; 11 | h[2] = 0; 12 | h[3] = 0; 13 | h[4] = 0; 14 | h[5] = 0; 15 | h[6] = 0; 16 | h[7] = 0; 17 | h[8] = 0; 18 | h[9] = 0; 19 | } 20 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_1.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = 1 5 | */ 6 | 7 | void fe_1(fe h) 8 | { 9 | h[0] = 1; 10 | h[1] = 0; 11 | h[2] = 0; 12 | h[3] = 0; 13 | h[4] = 0; 14 | h[5] = 0; 15 | h[6] = 0; 16 | h[7] = 0; 17 | h[8] = 0; 18 | h[9] = 0; 19 | } 20 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_add.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f + g 5 | Can overlap h with f or g. 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 9 | |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 10 | 11 | Postconditions: 12 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 13 | */ 14 | 15 | void fe_add(fe h,const fe f,const fe g) 16 | { 17 | crypto_int32 f0 = f[0]; 18 | crypto_int32 f1 = f[1]; 19 | crypto_int32 f2 = f[2]; 20 | crypto_int32 f3 = f[3]; 21 | crypto_int32 f4 = f[4]; 22 | crypto_int32 f5 = f[5]; 23 | crypto_int32 f6 = f[6]; 24 | crypto_int32 f7 = f[7]; 25 | crypto_int32 f8 = f[8]; 26 | crypto_int32 f9 = f[9]; 27 | crypto_int32 g0 = g[0]; 28 | crypto_int32 g1 = g[1]; 29 | crypto_int32 g2 = g[2]; 30 | crypto_int32 g3 = g[3]; 31 | crypto_int32 g4 = g[4]; 32 | crypto_int32 g5 = g[5]; 33 | crypto_int32 g6 = g[6]; 34 | crypto_int32 g7 = g[7]; 35 | crypto_int32 g8 = g[8]; 36 | crypto_int32 g9 = g[9]; 37 | crypto_int32 h0 = f0 + g0; 38 | crypto_int32 h1 = f1 + g1; 39 | crypto_int32 h2 = f2 + g2; 40 | crypto_int32 h3 = f3 + g3; 41 | crypto_int32 h4 = f4 + g4; 42 | crypto_int32 h5 = f5 + g5; 43 | crypto_int32 h6 = f6 + g6; 44 | crypto_int32 h7 = f7 + g7; 45 | crypto_int32 h8 = f8 + g8; 46 | crypto_int32 h9 = f9 + g9; 47 | h[0] = h0; 48 | h[1] = h1; 49 | h[2] = h2; 50 | h[3] = h3; 51 | h[4] = h4; 52 | h[5] = h5; 53 | h[6] = h6; 54 | h[7] = h7; 55 | h[8] = h8; 56 | h[9] = h9; 57 | } 58 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_cmov.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | Replace (f,g) with (g,g) if b == 1; 5 | replace (f,g) with (f,g) if b == 0. 6 | 7 | Preconditions: b in {0,1}. 8 | */ 9 | 10 | void fe_cmov(fe f,const fe g,unsigned int b) 11 | { 12 | crypto_int32 f0 = f[0]; 13 | crypto_int32 f1 = f[1]; 14 | crypto_int32 f2 = f[2]; 15 | crypto_int32 f3 = f[3]; 16 | crypto_int32 f4 = f[4]; 17 | crypto_int32 f5 = f[5]; 18 | crypto_int32 f6 = f[6]; 19 | crypto_int32 f7 = f[7]; 20 | crypto_int32 f8 = f[8]; 21 | crypto_int32 f9 = f[9]; 22 | crypto_int32 g0 = g[0]; 23 | crypto_int32 g1 = g[1]; 24 | crypto_int32 g2 = g[2]; 25 | crypto_int32 g3 = g[3]; 26 | crypto_int32 g4 = g[4]; 27 | crypto_int32 g5 = g[5]; 28 | crypto_int32 g6 = g[6]; 29 | crypto_int32 g7 = g[7]; 30 | crypto_int32 g8 = g[8]; 31 | crypto_int32 g9 = g[9]; 32 | crypto_int32 x0 = f0 ^ g0; 33 | crypto_int32 x1 = f1 ^ g1; 34 | crypto_int32 x2 = f2 ^ g2; 35 | crypto_int32 x3 = f3 ^ g3; 36 | crypto_int32 x4 = f4 ^ g4; 37 | crypto_int32 x5 = f5 ^ g5; 38 | crypto_int32 x6 = f6 ^ g6; 39 | crypto_int32 x7 = f7 ^ g7; 40 | crypto_int32 x8 = f8 ^ g8; 41 | crypto_int32 x9 = f9 ^ g9; 42 | //b = -b; 43 | b = (~b + 1u); 44 | x0 &= b; 45 | x1 &= b; 46 | x2 &= b; 47 | x3 &= b; 48 | x4 &= b; 49 | x5 &= b; 50 | x6 &= b; 51 | x7 &= b; 52 | x8 &= b; 53 | x9 &= b; 54 | f[0] = f0 ^ x0; 55 | f[1] = f1 ^ x1; 56 | f[2] = f2 ^ x2; 57 | f[3] = f3 ^ x3; 58 | f[4] = f4 ^ x4; 59 | f[5] = f5 ^ x5; 60 | f[6] = f6 ^ x6; 61 | f[7] = f7 ^ x7; 62 | f[8] = f8 ^ x8; 63 | f[9] = f9 ^ x9; 64 | } 65 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_copy.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f 5 | */ 6 | 7 | void fe_copy(fe h,const fe f) 8 | { 9 | crypto_int32 f0 = f[0]; 10 | crypto_int32 f1 = f[1]; 11 | crypto_int32 f2 = f[2]; 12 | crypto_int32 f3 = f[3]; 13 | crypto_int32 f4 = f[4]; 14 | crypto_int32 f5 = f[5]; 15 | crypto_int32 f6 = f[6]; 16 | crypto_int32 f7 = f[7]; 17 | crypto_int32 f8 = f[8]; 18 | crypto_int32 f9 = f[9]; 19 | h[0] = f0; 20 | h[1] = f1; 21 | h[2] = f2; 22 | h[3] = f3; 23 | h[4] = f4; 24 | h[5] = f5; 25 | h[6] = f6; 26 | h[7] = f7; 27 | h[8] = f8; 28 | h[9] = f9; 29 | } 30 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_frombytes.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_int64.h" 3 | #include "crypto_uint64.h" 4 | 5 | static crypto_uint64 load_3(const unsigned char *in) 6 | { 7 | crypto_uint64 result; 8 | result = (crypto_uint64) in[0]; 9 | result |= ((crypto_uint64) in[1]) << 8; 10 | result |= ((crypto_uint64) in[2]) << 16; 11 | return result; 12 | } 13 | 14 | static crypto_uint64 load_4(const unsigned char *in) 15 | { 16 | crypto_uint64 result; 17 | result = (crypto_uint64) in[0]; 18 | result |= ((crypto_uint64) in[1]) << 8; 19 | result |= ((crypto_uint64) in[2]) << 16; 20 | result |= ((crypto_uint64) in[3]) << 24; 21 | return result; 22 | } 23 | 24 | /* 25 | Ignores top bit of h. 26 | */ 27 | 28 | void fe_frombytes(fe h,const unsigned char *s) 29 | { 30 | crypto_int64 h0 = load_4(s); 31 | crypto_int64 h1 = load_3(s + 4) << 6; 32 | crypto_int64 h2 = load_3(s + 7) << 5; 33 | crypto_int64 h3 = load_3(s + 10) << 3; 34 | crypto_int64 h4 = load_3(s + 13) << 2; 35 | crypto_int64 h5 = load_4(s + 16); 36 | crypto_int64 h6 = load_3(s + 20) << 7; 37 | crypto_int64 h7 = load_3(s + 23) << 5; 38 | crypto_int64 h8 = load_3(s + 26) << 4; 39 | crypto_int64 h9 = (load_3(s + 29) & 8388607) << 2; 40 | crypto_int64 carry0; 41 | crypto_int64 carry1; 42 | crypto_int64 carry2; 43 | crypto_int64 carry3; 44 | crypto_int64 carry4; 45 | crypto_int64 carry5; 46 | crypto_int64 carry6; 47 | crypto_int64 carry7; 48 | crypto_int64 carry8; 49 | crypto_int64 carry9; 50 | 51 | carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 52 | carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 53 | carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 54 | carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 55 | carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 56 | 57 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 58 | carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 59 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 60 | carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 61 | carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 62 | 63 | h[0] = h0; 64 | h[1] = h1; 65 | h[2] = h2; 66 | h[3] = h3; 67 | h[4] = h4; 68 | h[5] = h5; 69 | h[6] = h6; 70 | h[7] = h7; 71 | h[8] = h8; 72 | h[9] = h9; 73 | } 74 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_invert.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_invert(fe out,const fe z) 4 | { 5 | fe t0; 6 | fe t1; 7 | fe t2; 8 | fe t3; 9 | int i; 10 | 11 | #include "pow225521.h" 12 | 13 | return; 14 | } 15 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_isnegative.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | return 1 if f is in {1,3,5,...,q-2} 5 | return 0 if f is in {0,2,4,...,q-1} 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 9 | */ 10 | 11 | int fe_isnegative(const fe f) 12 | { 13 | unsigned char s[32]; 14 | fe_tobytes(s,f); 15 | return s[0] & 1; 16 | } 17 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_isnonzero.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_verify_32.h" 3 | 4 | /* 5 | return nonzero if f == 0 6 | return 0 if f != 0 7 | 8 | Preconditions: 9 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 10 | */ 11 | 12 | /* TREVOR'S COMMENT 13 | * 14 | * I think the above comment is wrong. Instead: 15 | * 16 | * return 0 if f == 0 17 | * return -1 if f != 0 18 | * 19 | * */ 20 | 21 | static const unsigned char zero[32]; 22 | 23 | int fe_isnonzero(const fe f) 24 | { 25 | unsigned char s[32]; 26 | fe_tobytes(s,f); 27 | return crypto_verify_32(s,zero); 28 | } 29 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_neg.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = -f 5 | 6 | Preconditions: 7 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 8 | 9 | Postconditions: 10 | |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 11 | */ 12 | 13 | void fe_neg(fe h,const fe f) 14 | { 15 | crypto_int32 f0 = f[0]; 16 | crypto_int32 f1 = f[1]; 17 | crypto_int32 f2 = f[2]; 18 | crypto_int32 f3 = f[3]; 19 | crypto_int32 f4 = f[4]; 20 | crypto_int32 f5 = f[5]; 21 | crypto_int32 f6 = f[6]; 22 | crypto_int32 f7 = f[7]; 23 | crypto_int32 f8 = f[8]; 24 | crypto_int32 f9 = f[9]; 25 | crypto_int32 h0 = -f0; 26 | crypto_int32 h1 = -f1; 27 | crypto_int32 h2 = -f2; 28 | crypto_int32 h3 = -f3; 29 | crypto_int32 h4 = -f4; 30 | crypto_int32 h5 = -f5; 31 | crypto_int32 h6 = -f6; 32 | crypto_int32 h7 = -f7; 33 | crypto_int32 h8 = -f8; 34 | crypto_int32 h9 = -f9; 35 | h[0] = h0; 36 | h[1] = h1; 37 | h[2] = h2; 38 | h[3] = h3; 39 | h[4] = h4; 40 | h[5] = h5; 41 | h[6] = h6; 42 | h[7] = h7; 43 | h[8] = h8; 44 | h[9] = h9; 45 | } 46 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_pow22523.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_pow22523(fe out,const fe z) 4 | { 5 | fe t0; 6 | fe t1; 7 | fe t2; 8 | int i; 9 | 10 | #include "pow22523.h" 11 | 12 | return; 13 | } 14 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_sub.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f - g 5 | Can overlap h with f or g. 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 9 | |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 10 | 11 | Postconditions: 12 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 13 | */ 14 | 15 | void fe_sub(fe h,const fe f,const fe g) 16 | { 17 | crypto_int32 f0 = f[0]; 18 | crypto_int32 f1 = f[1]; 19 | crypto_int32 f2 = f[2]; 20 | crypto_int32 f3 = f[3]; 21 | crypto_int32 f4 = f[4]; 22 | crypto_int32 f5 = f[5]; 23 | crypto_int32 f6 = f[6]; 24 | crypto_int32 f7 = f[7]; 25 | crypto_int32 f8 = f[8]; 26 | crypto_int32 f9 = f[9]; 27 | crypto_int32 g0 = g[0]; 28 | crypto_int32 g1 = g[1]; 29 | crypto_int32 g2 = g[2]; 30 | crypto_int32 g3 = g[3]; 31 | crypto_int32 g4 = g[4]; 32 | crypto_int32 g5 = g[5]; 33 | crypto_int32 g6 = g[6]; 34 | crypto_int32 g7 = g[7]; 35 | crypto_int32 g8 = g[8]; 36 | crypto_int32 g9 = g[9]; 37 | crypto_int32 h0 = f0 - g0; 38 | crypto_int32 h1 = f1 - g1; 39 | crypto_int32 h2 = f2 - g2; 40 | crypto_int32 h3 = f3 - g3; 41 | crypto_int32 h4 = f4 - g4; 42 | crypto_int32 h5 = f5 - g5; 43 | crypto_int32 h6 = f6 - g6; 44 | crypto_int32 h7 = f7 - g7; 45 | crypto_int32 h8 = f8 - g8; 46 | crypto_int32 h9 = f9 - g9; 47 | h[0] = h0; 48 | h[1] = h1; 49 | h[2] = h2; 50 | h[3] = h3; 51 | h[4] = h4; 52 | h[5] = h5; 53 | h[6] = h6; 54 | h[7] = h7; 55 | h[8] = h8; 56 | h[9] = h9; 57 | } 58 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/fe_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | Preconditions: 5 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 6 | 7 | Write p=2^255-19; q=floor(h/p). 8 | Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). 9 | 10 | Proof: 11 | Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. 12 | Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. 13 | 14 | Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). 15 | Then 0> 25; 53 | q = (h0 + q) >> 26; 54 | q = (h1 + q) >> 25; 55 | q = (h2 + q) >> 26; 56 | q = (h3 + q) >> 25; 57 | q = (h4 + q) >> 26; 58 | q = (h5 + q) >> 25; 59 | q = (h6 + q) >> 26; 60 | q = (h7 + q) >> 25; 61 | q = (h8 + q) >> 26; 62 | q = (h9 + q) >> 25; 63 | 64 | /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ 65 | h0 += 19 * q; 66 | /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ 67 | 68 | carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; 69 | carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; 70 | carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; 71 | carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; 72 | carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; 73 | carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; 74 | carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; 75 | carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; 76 | carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; 77 | carry9 = h9 >> 25; h9 -= carry9 << 25; 78 | /* h10 = carry9 */ 79 | 80 | /* 81 | Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. 82 | Have h0+...+2^230 h9 between 0 and 2^255-1; 83 | evidently 2^255 h10-2^255 q = 0. 84 | Goal: Output h0+...+2^230 h9. 85 | */ 86 | 87 | s[0] = h0 >> 0; 88 | s[1] = h0 >> 8; 89 | s[2] = h0 >> 16; 90 | s[3] = (h0 >> 24) | (h1 << 2); 91 | s[4] = h1 >> 6; 92 | s[5] = h1 >> 14; 93 | s[6] = (h1 >> 22) | (h2 << 3); 94 | s[7] = h2 >> 5; 95 | s[8] = h2 >> 13; 96 | s[9] = (h2 >> 21) | (h3 << 5); 97 | s[10] = h3 >> 3; 98 | s[11] = h3 >> 11; 99 | s[12] = (h3 >> 19) | (h4 << 6); 100 | s[13] = h4 >> 2; 101 | s[14] = h4 >> 10; 102 | s[15] = h4 >> 18; 103 | s[16] = h5 >> 0; 104 | s[17] = h5 >> 8; 105 | s[18] = h5 >> 16; 106 | s[19] = (h5 >> 24) | (h6 << 1); 107 | s[20] = h6 >> 7; 108 | s[21] = h6 >> 15; 109 | s[22] = (h6 >> 23) | (h7 << 3); 110 | s[23] = h7 >> 5; 111 | s[24] = h7 >> 13; 112 | s[25] = (h7 >> 21) | (h8 << 4); 113 | s[26] = h8 >> 4; 114 | s[27] = h8 >> 12; 115 | s[28] = (h8 >> 20) | (h9 << 6); 116 | s[29] = h9 >> 2; 117 | s[30] = h9 >> 10; 118 | s[31] = h9 >> 18; 119 | } 120 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge.h: -------------------------------------------------------------------------------- 1 | #ifndef GE_H 2 | #define GE_H 3 | 4 | /* 5 | ge means group element. 6 | 7 | Here the group is the set of pairs (x,y) of field elements (see fe.h) 8 | satisfying -x^2 + y^2 = 1 + d x^2y^2 9 | where d = -121665/121666. 10 | 11 | Representations: 12 | ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z 13 | ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT 14 | ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T 15 | ge_precomp (Duif): (y+x,y-x,2dxy) 16 | */ 17 | 18 | #include "fe.h" 19 | 20 | typedef struct { 21 | fe X; 22 | fe Y; 23 | fe Z; 24 | } ge_p2; 25 | 26 | typedef struct { 27 | fe X; 28 | fe Y; 29 | fe Z; 30 | fe T; 31 | } ge_p3; 32 | 33 | typedef struct { 34 | fe X; 35 | fe Y; 36 | fe Z; 37 | fe T; 38 | } ge_p1p1; 39 | 40 | typedef struct { 41 | fe yplusx; 42 | fe yminusx; 43 | fe xy2d; 44 | } ge_precomp; 45 | 46 | typedef struct { 47 | fe YplusX; 48 | fe YminusX; 49 | fe Z; 50 | fe T2d; 51 | } ge_cached; 52 | 53 | #define ge_frombytes_negate_vartime crypto_sign_ed25519_ref10_ge_frombytes_negate_vartime 54 | #define ge_tobytes crypto_sign_ed25519_ref10_ge_tobytes 55 | #define ge_p3_tobytes crypto_sign_ed25519_ref10_ge_p3_tobytes 56 | 57 | #define ge_p2_0 crypto_sign_ed25519_ref10_ge_p2_0 58 | #define ge_p3_0 crypto_sign_ed25519_ref10_ge_p3_0 59 | #define ge_precomp_0 crypto_sign_ed25519_ref10_ge_precomp_0 60 | #define ge_p3_to_p2 crypto_sign_ed25519_ref10_ge_p3_to_p2 61 | #define ge_p3_to_cached crypto_sign_ed25519_ref10_ge_p3_to_cached 62 | #define ge_p1p1_to_p2 crypto_sign_ed25519_ref10_ge_p1p1_to_p2 63 | #define ge_p1p1_to_p3 crypto_sign_ed25519_ref10_ge_p1p1_to_p3 64 | #define ge_p2_dbl crypto_sign_ed25519_ref10_ge_p2_dbl 65 | #define ge_p3_dbl crypto_sign_ed25519_ref10_ge_p3_dbl 66 | 67 | #define ge_madd crypto_sign_ed25519_ref10_ge_madd 68 | #define ge_msub crypto_sign_ed25519_ref10_ge_msub 69 | #define ge_add crypto_sign_ed25519_ref10_ge_add 70 | #define ge_sub crypto_sign_ed25519_ref10_ge_sub 71 | #define ge_scalarmult_base crypto_sign_ed25519_ref10_ge_scalarmult_base 72 | #define ge_double_scalarmult_vartime crypto_sign_ed25519_ref10_ge_double_scalarmult_vartime 73 | 74 | extern void ge_tobytes(unsigned char *,const ge_p2 *); 75 | extern void ge_p3_tobytes(unsigned char *,const ge_p3 *); 76 | extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *); 77 | 78 | extern void ge_p2_0(ge_p2 *); 79 | extern void ge_p3_0(ge_p3 *); 80 | extern void ge_precomp_0(ge_precomp *); 81 | extern void ge_p3_to_p2(ge_p2 *,const ge_p3 *); 82 | extern void ge_p3_to_cached(ge_cached *,const ge_p3 *); 83 | extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *); 84 | extern void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *); 85 | extern void ge_p2_dbl(ge_p1p1 *,const ge_p2 *); 86 | extern void ge_p3_dbl(ge_p1p1 *,const ge_p3 *); 87 | 88 | extern void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *); 89 | extern void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *); 90 | extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *); 91 | extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *); 92 | extern void ge_scalarmult_base(ge_p3 *,const unsigned char *); 93 | extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *); 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_add.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p + q 5 | */ 6 | 7 | void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) 8 | { 9 | fe t0; 10 | #include "ge_add.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_add.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_add */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe Z2 */ 11 | 12 | /* qhasm: fe T1 */ 13 | 14 | /* qhasm: fe ZZ */ 15 | 16 | /* qhasm: fe YpX2 */ 17 | 18 | /* qhasm: fe YmX2 */ 19 | 20 | /* qhasm: fe T2d2 */ 21 | 22 | /* qhasm: fe X3 */ 23 | 24 | /* qhasm: fe Y3 */ 25 | 26 | /* qhasm: fe Z3 */ 27 | 28 | /* qhasm: fe T3 */ 29 | 30 | /* qhasm: fe YpX1 */ 31 | 32 | /* qhasm: fe YmX1 */ 33 | 34 | /* qhasm: fe A */ 35 | 36 | /* qhasm: fe B */ 37 | 38 | /* qhasm: fe C */ 39 | 40 | /* qhasm: fe D */ 41 | 42 | /* qhasm: YpX1 = Y1+X1 */ 43 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 45 | fe_add(r->X,p->Y,p->X); 46 | 47 | /* qhasm: YmX1 = Y1-X1 */ 48 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 50 | fe_sub(r->Y,p->Y,p->X); 51 | 52 | /* qhasm: A = YpX1*YpX2 */ 53 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YplusX); */ 55 | fe_mul(r->Z,r->X,q->YplusX); 56 | 57 | /* qhasm: B = YmX1*YmX2 */ 58 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YminusX); */ 60 | fe_mul(r->Y,r->Y,q->YminusX); 61 | 62 | /* qhasm: C = T2d2*T1 */ 63 | /* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ 65 | fe_mul(r->T,q->T2d,p->T); 66 | 67 | /* qhasm: ZZ = Z1*Z2 */ 68 | /* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ 70 | fe_mul(r->X,p->Z,q->Z); 71 | 72 | /* qhasm: D = 2*ZZ */ 73 | /* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ 75 | fe_add(t0,r->X,r->X); 76 | 77 | /* qhasm: X3 = A-B */ 78 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 80 | fe_sub(r->X,r->Z,r->Y); 81 | 82 | /* qhasm: Y3 = A+B */ 83 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 85 | fe_add(r->Y,r->Z,r->Y); 86 | 87 | /* qhasm: Z3 = D+C */ 88 | /* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ 90 | fe_add(r->Z,t0,r->T); 91 | 92 | /* qhasm: T3 = D-C */ 93 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ 95 | fe_sub(r->T,t0,r->T); 96 | 97 | /* qhasm: return */ 98 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_double_scalarmult.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | static void slide(signed char *r,const unsigned char *a) 4 | { 5 | int i; 6 | int b; 7 | int k; 8 | 9 | for (i = 0;i < 256;++i) 10 | r[i] = 1 & (a[i >> 3] >> (i & 7)); 11 | 12 | for (i = 0;i < 256;++i) 13 | if (r[i]) { 14 | for (b = 1;b <= 6 && i + b < 256;++b) { 15 | if (r[i + b]) { 16 | if (r[i] + (r[i + b] << b) <= 15) { 17 | r[i] += r[i + b] << b; r[i + b] = 0; 18 | } else if (r[i] - (r[i + b] << b) >= -15) { 19 | r[i] -= r[i + b] << b; 20 | for (k = i + b;k < 256;++k) { 21 | if (!r[k]) { 22 | r[k] = 1; 23 | break; 24 | } 25 | r[k] = 0; 26 | } 27 | } else 28 | break; 29 | } 30 | } 31 | } 32 | 33 | } 34 | 35 | static ge_precomp Bi[8] = { 36 | #include "base2.h" 37 | } ; 38 | 39 | /* 40 | r = a * A + b * B 41 | where a = a[0]+256*a[1]+...+256^31 a[31]. 42 | and b = b[0]+256*b[1]+...+256^31 b[31]. 43 | B is the Ed25519 base point (x,4/5) with x positive. 44 | */ 45 | 46 | void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b) 47 | { 48 | signed char aslide[256]; 49 | signed char bslide[256]; 50 | ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ 51 | ge_p1p1 t; 52 | ge_p3 u; 53 | ge_p3 A2; 54 | int i; 55 | 56 | slide(aslide,a); 57 | slide(bslide,b); 58 | 59 | ge_p3_to_cached(&Ai[0],A); 60 | ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); 61 | ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); 62 | ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); 63 | ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); 64 | ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); 65 | ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); 66 | ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); 67 | ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); 68 | 69 | ge_p2_0(r); 70 | 71 | for (i = 255;i >= 0;--i) { 72 | if (aslide[i] || bslide[i]) break; 73 | } 74 | 75 | for (;i >= 0;--i) { 76 | ge_p2_dbl(&t,r); 77 | 78 | if (aslide[i] > 0) { 79 | ge_p1p1_to_p3(&u,&t); 80 | ge_add(&t,&u,&Ai[aslide[i]/2]); 81 | } else if (aslide[i] < 0) { 82 | ge_p1p1_to_p3(&u,&t); 83 | ge_sub(&t,&u,&Ai[(-aslide[i])/2]); 84 | } 85 | 86 | if (bslide[i] > 0) { 87 | ge_p1p1_to_p3(&u,&t); 88 | ge_madd(&t,&u,&Bi[bslide[i]/2]); 89 | } else if (bslide[i] < 0) { 90 | ge_p1p1_to_p3(&u,&t); 91 | ge_msub(&t,&u,&Bi[(-bslide[i])/2]); 92 | } 93 | 94 | ge_p1p1_to_p2(r,&t); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_frombytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | static const fe d = { 4 | #include "d.h" 5 | } ; 6 | 7 | static const fe sqrtm1 = { 8 | #include "sqrtm1.h" 9 | } ; 10 | 11 | int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s) 12 | { 13 | fe u; 14 | fe v; 15 | fe v3; 16 | fe vxx; 17 | fe check; 18 | 19 | fe_frombytes(h->Y,s); 20 | fe_1(h->Z); 21 | fe_sq(u,h->Y); 22 | fe_mul(v,u,d); 23 | fe_sub(u,u,h->Z); /* u = y^2-1 */ 24 | fe_add(v,v,h->Z); /* v = dy^2+1 */ 25 | 26 | fe_sq(v3,v); 27 | fe_mul(v3,v3,v); /* v3 = v^3 */ 28 | fe_sq(h->X,v3); 29 | fe_mul(h->X,h->X,v); 30 | fe_mul(h->X,h->X,u); /* x = uv^7 */ 31 | 32 | fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ 33 | fe_mul(h->X,h->X,v3); 34 | fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ 35 | 36 | fe_sq(vxx,h->X); 37 | fe_mul(vxx,vxx,v); 38 | fe_sub(check,vxx,u); /* vx^2-u */ 39 | if (fe_isnonzero(check)) { 40 | fe_add(check,vxx,u); /* vx^2+u */ 41 | if (fe_isnonzero(check)) return -1; 42 | fe_mul(h->X,h->X,sqrtm1); 43 | } 44 | 45 | if (fe_isnegative(h->X) == (s[31] >> 7)) 46 | fe_neg(h->X,h->X); 47 | 48 | fe_mul(h->T,h->X,h->Y); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_madd.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p + q 5 | */ 6 | 7 | void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) 8 | { 9 | fe t0; 10 | #include "ge_madd.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_madd.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_madd */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe T1 */ 11 | 12 | /* qhasm: fe ypx2 */ 13 | 14 | /* qhasm: fe ymx2 */ 15 | 16 | /* qhasm: fe xy2d2 */ 17 | 18 | /* qhasm: fe X3 */ 19 | 20 | /* qhasm: fe Y3 */ 21 | 22 | /* qhasm: fe Z3 */ 23 | 24 | /* qhasm: fe T3 */ 25 | 26 | /* qhasm: fe YpX1 */ 27 | 28 | /* qhasm: fe YmX1 */ 29 | 30 | /* qhasm: fe A */ 31 | 32 | /* qhasm: fe B */ 33 | 34 | /* qhasm: fe C */ 35 | 36 | /* qhasm: fe D */ 37 | 38 | /* qhasm: YpX1 = Y1+X1 */ 39 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 41 | fe_add(r->X,p->Y,p->X); 42 | 43 | /* qhasm: YmX1 = Y1-X1 */ 44 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 46 | fe_sub(r->Y,p->Y,p->X); 47 | 48 | /* qhasm: A = YpX1*ypx2 */ 49 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yplusx); */ 51 | fe_mul(r->Z,r->X,q->yplusx); 52 | 53 | /* qhasm: B = YmX1*ymx2 */ 54 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yminusx); */ 56 | fe_mul(r->Y,r->Y,q->yminusx); 57 | 58 | /* qhasm: C = xy2d2*T1 */ 59 | /* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ 61 | fe_mul(r->T,q->xy2d,p->T); 62 | 63 | /* qhasm: D = 2*Z1 */ 64 | /* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ 66 | fe_add(t0,p->Z,p->Z); 67 | 68 | /* qhasm: X3 = A-B */ 69 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 71 | fe_sub(r->X,r->Z,r->Y); 72 | 73 | /* qhasm: Y3 = A+B */ 74 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 76 | fe_add(r->Y,r->Z,r->Y); 77 | 78 | /* qhasm: Z3 = D+C */ 79 | /* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ 81 | fe_add(r->Z,t0,r->T); 82 | 83 | /* qhasm: T3 = D-C */ 84 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ 86 | fe_sub(r->T,t0,r->T); 87 | 88 | /* qhasm: return */ 89 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_msub.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p - q 5 | */ 6 | 7 | void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) 8 | { 9 | fe t0; 10 | #include "ge_msub.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_msub.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_msub */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe T1 */ 11 | 12 | /* qhasm: fe ypx2 */ 13 | 14 | /* qhasm: fe ymx2 */ 15 | 16 | /* qhasm: fe xy2d2 */ 17 | 18 | /* qhasm: fe X3 */ 19 | 20 | /* qhasm: fe Y3 */ 21 | 22 | /* qhasm: fe Z3 */ 23 | 24 | /* qhasm: fe T3 */ 25 | 26 | /* qhasm: fe YpX1 */ 27 | 28 | /* qhasm: fe YmX1 */ 29 | 30 | /* qhasm: fe A */ 31 | 32 | /* qhasm: fe B */ 33 | 34 | /* qhasm: fe C */ 35 | 36 | /* qhasm: fe D */ 37 | 38 | /* qhasm: YpX1 = Y1+X1 */ 39 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 41 | fe_add(r->X,p->Y,p->X); 42 | 43 | /* qhasm: YmX1 = Y1-X1 */ 44 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 46 | fe_sub(r->Y,p->Y,p->X); 47 | 48 | /* qhasm: A = YpX1*ymx2 */ 49 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yminusx); */ 51 | fe_mul(r->Z,r->X,q->yminusx); 52 | 53 | /* qhasm: B = YmX1*ypx2 */ 54 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yplusx); */ 56 | fe_mul(r->Y,r->Y,q->yplusx); 57 | 58 | /* qhasm: C = xy2d2*T1 */ 59 | /* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ 61 | fe_mul(r->T,q->xy2d,p->T); 62 | 63 | /* qhasm: D = 2*Z1 */ 64 | /* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ 66 | fe_add(t0,p->Z,p->Z); 67 | 68 | /* qhasm: X3 = A-B */ 69 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 71 | fe_sub(r->X,r->Z,r->Y); 72 | 73 | /* qhasm: Y3 = A+B */ 74 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 76 | fe_add(r->Y,r->Z,r->Y); 77 | 78 | /* qhasm: Z3 = D-C */ 79 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ 81 | fe_sub(r->Z,t0,r->T); 82 | 83 | /* qhasm: T3 = D+C */ 84 | /* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ 86 | fe_add(r->T,t0,r->T); 87 | 88 | /* qhasm: return */ 89 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p1p1_to_p2.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p) 8 | { 9 | fe_mul(r->X,p->X,p->T); 10 | fe_mul(r->Y,p->Y,p->Z); 11 | fe_mul(r->Z,p->Z,p->T); 12 | } 13 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p1p1_to_p3.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p) 8 | { 9 | fe_mul(r->X,p->X,p->T); 10 | fe_mul(r->Y,p->Y,p->Z); 11 | fe_mul(r->Z,p->Z,p->T); 12 | fe_mul(r->T,p->X,p->Y); 13 | } 14 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p2_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p2_0(ge_p2 *h) 4 | { 5 | fe_0(h->X); 6 | fe_1(h->Y); 7 | fe_1(h->Z); 8 | } 9 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p2_dbl.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = 2 * p 5 | */ 6 | 7 | void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p) 8 | { 9 | fe t0; 10 | #include "ge_p2_dbl.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p2_dbl.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_p2_dbl */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe A */ 11 | 12 | /* qhasm: fe AA */ 13 | 14 | /* qhasm: fe XX */ 15 | 16 | /* qhasm: fe YY */ 17 | 18 | /* qhasm: fe B */ 19 | 20 | /* qhasm: fe X3 */ 21 | 22 | /* qhasm: fe Y3 */ 23 | 24 | /* qhasm: fe Z3 */ 25 | 26 | /* qhasm: fe T3 */ 27 | 28 | /* qhasm: XX=X1^2 */ 29 | /* asm 1: fe_sq(>XX=fe#1,XX=r->X,X); */ 31 | fe_sq(r->X,p->X); 32 | 33 | /* qhasm: YY=Y1^2 */ 34 | /* asm 1: fe_sq(>YY=fe#3,YY=r->Z,Y); */ 36 | fe_sq(r->Z,p->Y); 37 | 38 | /* qhasm: B=2*Z1^2 */ 39 | /* asm 1: fe_sq2(>B=fe#4,B=r->T,Z); */ 41 | fe_sq2(r->T,p->Z); 42 | 43 | /* qhasm: A=X1+Y1 */ 44 | /* asm 1: fe_add(>A=fe#2,A=r->Y,X,Y); */ 46 | fe_add(r->Y,p->X,p->Y); 47 | 48 | /* qhasm: AA=A^2 */ 49 | /* asm 1: fe_sq(>AA=fe#5,AA=t0,Y); */ 51 | fe_sq(t0,r->Y); 52 | 53 | /* qhasm: Y3=YY+XX */ 54 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,X); */ 56 | fe_add(r->Y,r->Z,r->X); 57 | 58 | /* qhasm: Z3=YY-XX */ 59 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,Z,X); */ 61 | fe_sub(r->Z,r->Z,r->X); 62 | 63 | /* qhasm: X3=AA-Y3 */ 64 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Y); */ 66 | fe_sub(r->X,t0,r->Y); 67 | 68 | /* qhasm: T3=B-Z3 */ 69 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T,Z); */ 71 | fe_sub(r->T,r->T,r->Z); 72 | 73 | /* qhasm: return */ 74 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p3_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p3_0(ge_p3 *h) 4 | { 5 | fe_0(h->X); 6 | fe_1(h->Y); 7 | fe_1(h->Z); 8 | fe_0(h->T); 9 | } 10 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p3_dbl.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = 2 * p 5 | */ 6 | 7 | void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p) 8 | { 9 | ge_p2 q; 10 | ge_p3_to_p2(&q,p); 11 | ge_p2_dbl(r,&q); 12 | } 13 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p3_to_cached.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | static const fe d2 = { 8 | #include "d2.h" 9 | } ; 10 | 11 | extern void ge_p3_to_cached(ge_cached *r,const ge_p3 *p) 12 | { 13 | fe_add(r->YplusX,p->Y,p->X); 14 | fe_sub(r->YminusX,p->Y,p->X); 15 | fe_copy(r->Z,p->Z); 16 | fe_mul(r->T2d,p->T,d2); 17 | } 18 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p3_to_p2.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p) 8 | { 9 | fe_copy(r->X,p->X); 10 | fe_copy(r->Y,p->Y); 11 | fe_copy(r->Z,p->Z); 12 | } 13 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_p3_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p3_tobytes(unsigned char *s,const ge_p3 *h) 4 | { 5 | fe recip; 6 | fe x; 7 | fe y; 8 | 9 | fe_invert(recip,h->Z); 10 | fe_mul(x,h->X,recip); 11 | fe_mul(y,h->Y,recip); 12 | fe_tobytes(s,y); 13 | s[31] ^= fe_isnegative(x) << 7; 14 | } 15 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_precomp_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_precomp_0(ge_precomp *h) 4 | { 5 | fe_1(h->yplusx); 6 | fe_1(h->yminusx); 7 | fe_0(h->xy2d); 8 | } 9 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_scalarmult_base.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | #include "crypto_uint32.h" 3 | 4 | static unsigned char equal(signed char b,signed char c) 5 | { 6 | unsigned char ub = b; 7 | unsigned char uc = c; 8 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 9 | crypto_uint32 y = x; /* 0: yes; 1..255: no */ 10 | y -= 1; /* 4294967295: yes; 0..254: no */ 11 | y >>= 31; /* 1: yes; 0: no */ 12 | return y; 13 | } 14 | 15 | static unsigned char negative(signed char b) 16 | { 17 | unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 18 | x >>= 63; /* 1: yes; 0: no */ 19 | return x; 20 | } 21 | 22 | static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b) 23 | { 24 | fe_cmov(t->yplusx,u->yplusx,b); 25 | fe_cmov(t->yminusx,u->yminusx,b); 26 | fe_cmov(t->xy2d,u->xy2d,b); 27 | } 28 | 29 | /* base[i][j] = (j+1)*256^i*B */ 30 | static ge_precomp base[32][8] = { 31 | #include "base.h" 32 | } ; 33 | 34 | static void select(ge_precomp *t,int pos,signed char b) 35 | { 36 | ge_precomp minust; 37 | unsigned char bnegative = negative(b); 38 | unsigned char babs = b - (((-bnegative) & b) << 1); 39 | 40 | ge_precomp_0(t); 41 | cmov(t,&base[pos][0],equal(babs,1)); 42 | cmov(t,&base[pos][1],equal(babs,2)); 43 | cmov(t,&base[pos][2],equal(babs,3)); 44 | cmov(t,&base[pos][3],equal(babs,4)); 45 | cmov(t,&base[pos][4],equal(babs,5)); 46 | cmov(t,&base[pos][5],equal(babs,6)); 47 | cmov(t,&base[pos][6],equal(babs,7)); 48 | cmov(t,&base[pos][7],equal(babs,8)); 49 | fe_copy(minust.yplusx,t->yminusx); 50 | fe_copy(minust.yminusx,t->yplusx); 51 | fe_neg(minust.xy2d,t->xy2d); 52 | cmov(t,&minust,bnegative); 53 | } 54 | 55 | /* 56 | h = a * B 57 | where a = a[0]+256*a[1]+...+256^31 a[31] 58 | B is the Ed25519 base point (x,4/5) with x positive. 59 | 60 | Preconditions: 61 | a[31] <= 127 62 | */ 63 | 64 | void ge_scalarmult_base(ge_p3 *h,const unsigned char *a) 65 | { 66 | signed char e[64]; 67 | signed char carry; 68 | ge_p1p1 r; 69 | ge_p2 s; 70 | ge_precomp t; 71 | int i; 72 | 73 | for (i = 0;i < 32;++i) { 74 | e[2 * i + 0] = (a[i] >> 0) & 15; 75 | e[2 * i + 1] = (a[i] >> 4) & 15; 76 | } 77 | /* each e[i] is between 0 and 15 */ 78 | /* e[63] is between 0 and 7 */ 79 | 80 | carry = 0; 81 | for (i = 0;i < 63;++i) { 82 | e[i] += carry; 83 | carry = e[i] + 8; 84 | carry >>= 4; 85 | e[i] -= carry << 4; 86 | } 87 | e[63] += carry; 88 | /* each e[i] is between -8 and 8 */ 89 | 90 | ge_p3_0(h); 91 | for (i = 1;i < 64;i += 2) { 92 | select(&t,i / 2,e[i]); 93 | ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); 94 | } 95 | 96 | ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r); 97 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 98 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 99 | ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); 100 | 101 | for (i = 0;i < 64;i += 2) { 102 | select(&t,i / 2,e[i]); 103 | ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_sub.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p - q 5 | */ 6 | 7 | void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) 8 | { 9 | fe t0; 10 | #include "ge_sub.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_sub.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_sub */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe Z2 */ 11 | 12 | /* qhasm: fe T1 */ 13 | 14 | /* qhasm: fe ZZ */ 15 | 16 | /* qhasm: fe YpX2 */ 17 | 18 | /* qhasm: fe YmX2 */ 19 | 20 | /* qhasm: fe T2d2 */ 21 | 22 | /* qhasm: fe X3 */ 23 | 24 | /* qhasm: fe Y3 */ 25 | 26 | /* qhasm: fe Z3 */ 27 | 28 | /* qhasm: fe T3 */ 29 | 30 | /* qhasm: fe YpX1 */ 31 | 32 | /* qhasm: fe YmX1 */ 33 | 34 | /* qhasm: fe A */ 35 | 36 | /* qhasm: fe B */ 37 | 38 | /* qhasm: fe C */ 39 | 40 | /* qhasm: fe D */ 41 | 42 | /* qhasm: YpX1 = Y1+X1 */ 43 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 45 | fe_add(r->X,p->Y,p->X); 46 | 47 | /* qhasm: YmX1 = Y1-X1 */ 48 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 50 | fe_sub(r->Y,p->Y,p->X); 51 | 52 | /* qhasm: A = YpX1*YmX2 */ 53 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YminusX); */ 55 | fe_mul(r->Z,r->X,q->YminusX); 56 | 57 | /* qhasm: B = YmX1*YpX2 */ 58 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YplusX); */ 60 | fe_mul(r->Y,r->Y,q->YplusX); 61 | 62 | /* qhasm: C = T2d2*T1 */ 63 | /* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ 65 | fe_mul(r->T,q->T2d,p->T); 66 | 67 | /* qhasm: ZZ = Z1*Z2 */ 68 | /* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ 70 | fe_mul(r->X,p->Z,q->Z); 71 | 72 | /* qhasm: D = 2*ZZ */ 73 | /* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ 75 | fe_add(t0,r->X,r->X); 76 | 77 | /* qhasm: X3 = A-B */ 78 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 80 | fe_sub(r->X,r->Z,r->Y); 81 | 82 | /* qhasm: Y3 = A+B */ 83 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 85 | fe_add(r->Y,r->Z,r->Y); 86 | 87 | /* qhasm: Z3 = D-C */ 88 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ 90 | fe_sub(r->Z,t0,r->T); 91 | 92 | /* qhasm: T3 = D+C */ 93 | /* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ 95 | fe_add(r->T,t0,r->T); 96 | 97 | /* qhasm: return */ 98 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/ge_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_tobytes(unsigned char *s,const ge_p2 *h) 4 | { 5 | fe recip; 6 | fe x; 7 | fe y; 8 | 9 | fe_invert(recip,h->Z); 10 | fe_mul(x,h->X,recip); 11 | fe_mul(y,h->Y,recip); 12 | fe_tobytes(s,y); 13 | s[31] ^= fe_isnegative(x) << 7; 14 | } 15 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/main/main.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | all_fast_tests(0); 7 | curvesigs_slow_test(0, 10000); 8 | xeddsa_slow_test(0, 10000); 9 | xeddsa_to_curvesigs_slow_test(0, 10000); 10 | vxeddsa_slow_test(0, 10000000); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/nacl_includes/crypto_int32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_int32_h 2 | #define crypto_int32_h 3 | 4 | typedef int crypto_int32; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/nacl_includes/crypto_int64.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_int64_h 2 | #define crypto_int64_h 3 | 4 | typedef long long crypto_int64; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/nacl_includes/crypto_sign.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_sign_H 2 | #define crypto_sign_H 3 | 4 | #include "crypto_sign_edwards25519sha512batch.h" 5 | 6 | #define crypto_sign crypto_sign_edwards25519sha512batch 7 | #define crypto_sign_open crypto_sign_edwards25519sha512batch_open 8 | #define crypto_sign_keypair crypto_sign_edwards25519sha512batch_keypair 9 | #define crypto_sign_BYTES crypto_sign_edwards25519sha512batch_BYTES 10 | #define crypto_sign_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 11 | #define crypto_sign_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_SECRETKEYBYTES 12 | #define crypto_sign_PRIMITIVE "edwards25519sha512batch" 13 | #define crypto_sign_IMPLEMENTATION crypto_sign_edwards25519sha512batch_IMPLEMENTATION 14 | #define crypto_sign_VERSION crypto_sign_edwards25519sha512batch_VERSION 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/nacl_includes/crypto_sign_edwards25519sha512batch.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_sign_edwards25519sha512batch_H 2 | #define crypto_sign_edwards25519sha512batch_H 3 | 4 | #define crypto_sign_edwards25519sha512batch_ref10_SECRETKEYBYTES 64 5 | #define crypto_sign_edwards25519sha512batch_ref10_PUBLICKEYBYTES 32 6 | #define crypto_sign_edwards25519sha512batch_ref10_BYTES 64 7 | #ifdef __cplusplus 8 | #include 9 | extern std::string crypto_sign_edwards25519sha512batch_ref10(const std::string &,const std::string &); 10 | extern std::string crypto_sign_edwards25519sha512batch_ref10_open(const std::string &,const std::string &); 11 | extern std::string crypto_sign_edwards25519sha512batch_ref10_keypair(std::string *); 12 | extern "C" { 13 | #endif 14 | extern int crypto_sign_edwards25519sha512batch_ref10(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); 15 | extern int crypto_sign_edwards25519sha512batch_ref10_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); 16 | extern int crypto_sign_edwards25519sha512batch_ref10_keypair(unsigned char *,unsigned char *); 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #define crypto_sign_edwards25519sha512batch crypto_sign_edwards25519sha512batch_ref10 22 | #define crypto_sign_edwards25519sha512batch_open crypto_sign_edwards25519sha512batch_ref10_open 23 | #define crypto_sign_edwards25519sha512batch_keypair crypto_sign_edwards25519sha512batch_ref10_keypair 24 | #define crypto_sign_edwards25519sha512batch_BYTES crypto_sign_edwards25519sha512batch_ref10_BYTES 25 | #define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_ref10_PUBLICKEYBYTES 26 | #define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_ref10_SECRETKEYBYTES 27 | #define crypto_sign_edwards25519sha512batch_IMPLEMENTATION "crypto_sign/edwards25519sha512batch/ref10" 28 | #ifndef crypto_sign_edwards25519sha512batch_ref10_VERSION 29 | #define crypto_sign_edwards25519sha512batch_ref10_VERSION "-" 30 | #endif 31 | #define crypto_sign_edwards25519sha512batch_VERSION crypto_sign_edwards25519sha512batch_ref10_VERSION 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/nacl_includes/crypto_uint32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_uint32_h 2 | #define crypto_uint32_h 3 | 4 | typedef unsigned int crypto_uint32; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/nacl_includes/crypto_uint64.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_uint64_h 2 | #define crypto_uint64_h 3 | 4 | typedef unsigned long long crypto_uint64; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/nacl_includes/crypto_verify_32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_verify_32_H 2 | #define crypto_verify_32_H 3 | 4 | #define crypto_verify_32_ref_BYTES 32 5 | #ifdef __cplusplus 6 | #include 7 | extern "C" { 8 | #endif 9 | extern int crypto_verify_32_ref(const unsigned char *,const unsigned char *); 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #define crypto_verify_32 crypto_verify_32_ref 15 | #define crypto_verify_32_BYTES crypto_verify_32_ref_BYTES 16 | #define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/ref" 17 | #ifndef crypto_verify_32_ref_VERSION 18 | #define crypto_verify_32_ref_VERSION "-" 19 | #endif 20 | #define crypto_verify_32_VERSION crypto_verify_32_ref_VERSION 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/nacl_sha512/hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | 20080913 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #include 8 | typedef uint64_t uint64; 9 | 10 | extern int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen); 11 | 12 | #define blocks crypto_hashblocks_sha512 13 | 14 | static const unsigned char iv[64] = { 15 | 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, 16 | 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, 17 | 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, 18 | 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, 19 | 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, 20 | 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, 21 | 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, 22 | 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 23 | } ; 24 | 25 | int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen) 26 | { 27 | unsigned char h[64]; 28 | unsigned char padded[256]; 29 | int i; 30 | unsigned long long bytes = inlen; 31 | 32 | for (i = 0;i < 64;++i) h[i] = iv[i]; 33 | 34 | blocks(h,in,inlen); 35 | in += inlen; 36 | inlen &= 127; 37 | in -= inlen; 38 | 39 | for (i = 0;i < inlen;++i) padded[i] = in[i]; 40 | padded[inlen] = 0x80; 41 | 42 | if (inlen < 112) { 43 | for (i = inlen + 1;i < 119;++i) padded[i] = 0; 44 | padded[119] = bytes >> 61; 45 | padded[120] = bytes >> 53; 46 | padded[121] = bytes >> 45; 47 | padded[122] = bytes >> 37; 48 | padded[123] = bytes >> 29; 49 | padded[124] = bytes >> 21; 50 | padded[125] = bytes >> 13; 51 | padded[126] = bytes >> 5; 52 | padded[127] = bytes << 3; 53 | blocks(h,padded,128); 54 | } else { 55 | for (i = inlen + 1;i < 247;++i) padded[i] = 0; 56 | padded[247] = bytes >> 61; 57 | padded[248] = bytes >> 53; 58 | padded[249] = bytes >> 45; 59 | padded[250] = bytes >> 37; 60 | padded[251] = bytes >> 29; 61 | padded[252] = bytes >> 21; 62 | padded[253] = bytes >> 13; 63 | padded[254] = bytes >> 5; 64 | padded[255] = bytes << 3; 65 | blocks(h,padded,256); 66 | } 67 | 68 | for (i = 0;i < 64;++i) out[i] = h[i]; 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/open.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "crypto_verify_32.h" 5 | #include "ge.h" 6 | #include "sc.h" 7 | 8 | int crypto_sign_open( 9 | unsigned char *m,unsigned long long *mlen, 10 | const unsigned char *sm,unsigned long long smlen, 11 | const unsigned char *pk 12 | ) 13 | { 14 | unsigned char pkcopy[32]; 15 | unsigned char rcopy[32]; 16 | unsigned char scopy[32]; 17 | unsigned char h[64]; 18 | unsigned char rcheck[32]; 19 | ge_p3 A; 20 | ge_p2 R; 21 | 22 | if (smlen < 64) goto badsig; 23 | if (sm[63] & 224) goto badsig; 24 | if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; 25 | 26 | memmove(pkcopy,pk,32); 27 | memmove(rcopy,sm,32); 28 | memmove(scopy,sm + 32,32); 29 | 30 | memmove(m,sm,smlen); 31 | memmove(m + 32,pkcopy,32); 32 | crypto_hash_sha512(h,m,smlen); 33 | sc_reduce(h); 34 | 35 | ge_double_scalarmult_vartime(&R,h,&A,scopy); 36 | ge_tobytes(rcheck,&R); 37 | if (crypto_verify_32(rcheck,rcopy) == 0) { 38 | memmove(m,m + 64,smlen - 64); 39 | memset(m + smlen - 64,0,64); 40 | *mlen = smlen - 64; 41 | return 0; 42 | } 43 | 44 | badsig: 45 | *mlen = -1; 46 | memset(m,0,smlen); 47 | return -1; 48 | } 49 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/pow22523.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: fe z1 */ 3 | 4 | /* qhasm: fe z2 */ 5 | 6 | /* qhasm: fe z8 */ 7 | 8 | /* qhasm: fe z9 */ 9 | 10 | /* qhasm: fe z11 */ 11 | 12 | /* qhasm: fe z22 */ 13 | 14 | /* qhasm: fe z_5_0 */ 15 | 16 | /* qhasm: fe z_10_5 */ 17 | 18 | /* qhasm: fe z_10_0 */ 19 | 20 | /* qhasm: fe z_20_10 */ 21 | 22 | /* qhasm: fe z_20_0 */ 23 | 24 | /* qhasm: fe z_40_20 */ 25 | 26 | /* qhasm: fe z_40_0 */ 27 | 28 | /* qhasm: fe z_50_10 */ 29 | 30 | /* qhasm: fe z_50_0 */ 31 | 32 | /* qhasm: fe z_100_50 */ 33 | 34 | /* qhasm: fe z_100_0 */ 35 | 36 | /* qhasm: fe z_200_100 */ 37 | 38 | /* qhasm: fe z_200_0 */ 39 | 40 | /* qhasm: fe z_250_50 */ 41 | 42 | /* qhasm: fe z_250_0 */ 43 | 44 | /* qhasm: fe z_252_2 */ 45 | 46 | /* qhasm: fe z_252_3 */ 47 | 48 | /* qhasm: enter pow22523 */ 49 | 50 | /* qhasm: z2 = z1^2^1 */ 51 | /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ 52 | /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ 53 | fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); 54 | 55 | /* qhasm: z8 = z2^2^2 */ 56 | /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ 57 | /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ 58 | fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); 59 | 60 | /* qhasm: z9 = z1*z8 */ 61 | /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#1,z22=fe#1,>z22=fe#1); */ 72 | /* asm 2: fe_sq(>z22=t0,z22=t0,>z22=t0); */ 73 | fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0); 74 | 75 | /* qhasm: z_5_0 = z9*z22 */ 76 | /* asm 1: fe_mul(>z_5_0=fe#1,z_5_0=t0,z_10_5=fe#2,z_10_5=fe#2,>z_10_5=fe#2); */ 82 | /* asm 2: fe_sq(>z_10_5=t1,z_10_5=t1,>z_10_5=t1); */ 83 | fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1); 84 | 85 | /* qhasm: z_10_0 = z_10_5*z_5_0 */ 86 | /* asm 1: fe_mul(>z_10_0=fe#1,z_10_0=t0,z_20_10=fe#2,z_20_10=fe#2,>z_20_10=fe#2); */ 92 | /* asm 2: fe_sq(>z_20_10=t1,z_20_10=t1,>z_20_10=t1); */ 93 | fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1); 94 | 95 | /* qhasm: z_20_0 = z_20_10*z_10_0 */ 96 | /* asm 1: fe_mul(>z_20_0=fe#2,z_20_0=t1,z_40_20=fe#3,z_40_20=fe#3,>z_40_20=fe#3); */ 102 | /* asm 2: fe_sq(>z_40_20=t2,z_40_20=t2,>z_40_20=t2); */ 103 | fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2); 104 | 105 | /* qhasm: z_40_0 = z_40_20*z_20_0 */ 106 | /* asm 1: fe_mul(>z_40_0=fe#2,z_40_0=t1,z_50_10=fe#2,z_50_10=fe#2,>z_50_10=fe#2); */ 112 | /* asm 2: fe_sq(>z_50_10=t1,z_50_10=t1,>z_50_10=t1); */ 113 | fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1); 114 | 115 | /* qhasm: z_50_0 = z_50_10*z_10_0 */ 116 | /* asm 1: fe_mul(>z_50_0=fe#1,z_50_0=t0,z_100_50=fe#2,z_100_50=fe#2,>z_100_50=fe#2); */ 122 | /* asm 2: fe_sq(>z_100_50=t1,z_100_50=t1,>z_100_50=t1); */ 123 | fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1); 124 | 125 | /* qhasm: z_100_0 = z_100_50*z_50_0 */ 126 | /* asm 1: fe_mul(>z_100_0=fe#2,z_100_0=t1,z_200_100=fe#3,z_200_100=fe#3,>z_200_100=fe#3); */ 132 | /* asm 2: fe_sq(>z_200_100=t2,z_200_100=t2,>z_200_100=t2); */ 133 | fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2); 134 | 135 | /* qhasm: z_200_0 = z_200_100*z_100_0 */ 136 | /* asm 1: fe_mul(>z_200_0=fe#2,z_200_0=t1,z_250_50=fe#2,z_250_50=fe#2,>z_250_50=fe#2); */ 142 | /* asm 2: fe_sq(>z_250_50=t1,z_250_50=t1,>z_250_50=t1); */ 143 | fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1); 144 | 145 | /* qhasm: z_250_0 = z_250_50*z_50_0 */ 146 | /* asm 1: fe_mul(>z_250_0=fe#1,z_250_0=t0,z_252_2=fe#1,z_252_2=fe#1,>z_252_2=fe#1); */ 152 | /* asm 2: fe_sq(>z_252_2=t0,z_252_2=t0,>z_252_2=t0); */ 153 | fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0); 154 | 155 | /* qhasm: z_252_3 = z_252_2*z1 */ 156 | /* asm 1: fe_mul(>z_252_3=fe#12,z_252_3=out,z2=fe#1,z2=fe#1,>z2=fe#1); */ 52 | /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ 53 | fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); 54 | 55 | /* qhasm: z8 = z2^2^2 */ 56 | /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ 57 | /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ 58 | fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); 59 | 60 | /* qhasm: z9 = z1*z8 */ 61 | /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#3,z22=fe#3,>z22=fe#3); */ 72 | /* asm 2: fe_sq(>z22=t2,z22=t2,>z22=t2); */ 73 | fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2); 74 | 75 | /* qhasm: z_5_0 = z9*z22 */ 76 | /* asm 1: fe_mul(>z_5_0=fe#2,z_5_0=t1,z_10_5=fe#3,z_10_5=fe#3,>z_10_5=fe#3); */ 82 | /* asm 2: fe_sq(>z_10_5=t2,z_10_5=t2,>z_10_5=t2); */ 83 | fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2); 84 | 85 | /* qhasm: z_10_0 = z_10_5*z_5_0 */ 86 | /* asm 1: fe_mul(>z_10_0=fe#2,z_10_0=t1,z_20_10=fe#3,z_20_10=fe#3,>z_20_10=fe#3); */ 92 | /* asm 2: fe_sq(>z_20_10=t2,z_20_10=t2,>z_20_10=t2); */ 93 | fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2); 94 | 95 | /* qhasm: z_20_0 = z_20_10*z_10_0 */ 96 | /* asm 1: fe_mul(>z_20_0=fe#3,z_20_0=t2,z_40_20=fe#4,z_40_20=fe#4,>z_40_20=fe#4); */ 102 | /* asm 2: fe_sq(>z_40_20=t3,z_40_20=t3,>z_40_20=t3); */ 103 | fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3); 104 | 105 | /* qhasm: z_40_0 = z_40_20*z_20_0 */ 106 | /* asm 1: fe_mul(>z_40_0=fe#3,z_40_0=t2,z_50_10=fe#3,z_50_10=fe#3,>z_50_10=fe#3); */ 112 | /* asm 2: fe_sq(>z_50_10=t2,z_50_10=t2,>z_50_10=t2); */ 113 | fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2); 114 | 115 | /* qhasm: z_50_0 = z_50_10*z_10_0 */ 116 | /* asm 1: fe_mul(>z_50_0=fe#2,z_50_0=t1,z_100_50=fe#3,z_100_50=fe#3,>z_100_50=fe#3); */ 122 | /* asm 2: fe_sq(>z_100_50=t2,z_100_50=t2,>z_100_50=t2); */ 123 | fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2); 124 | 125 | /* qhasm: z_100_0 = z_100_50*z_50_0 */ 126 | /* asm 1: fe_mul(>z_100_0=fe#3,z_100_0=t2,z_200_100=fe#4,z_200_100=fe#4,>z_200_100=fe#4); */ 132 | /* asm 2: fe_sq(>z_200_100=t3,z_200_100=t3,>z_200_100=t3); */ 133 | fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3); 134 | 135 | /* qhasm: z_200_0 = z_200_100*z_100_0 */ 136 | /* asm 1: fe_mul(>z_200_0=fe#3,z_200_0=t2,z_250_50=fe#3,z_250_50=fe#3,>z_250_50=fe#3); */ 142 | /* asm 2: fe_sq(>z_250_50=t2,z_250_50=t2,>z_250_50=t2); */ 143 | fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2); 144 | 145 | /* qhasm: z_250_0 = z_250_50*z_50_0 */ 146 | /* asm 1: fe_mul(>z_250_0=fe#2,z_250_0=t1,z_255_5=fe#2,z_255_5=fe#2,>z_255_5=fe#2); */ 152 | /* asm 2: fe_sq(>z_255_5=t1,z_255_5=t1,>z_255_5=t1); */ 153 | fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1); 154 | 155 | /* qhasm: z_255_21 = z_255_5*z11 */ 156 | /* asm 1: fe_mul(>z_255_21=fe#12,z_255_21=out, 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "ge.h" 5 | #include "sc.h" 6 | 7 | int crypto_sign( 8 | unsigned char *sm,unsigned long long *smlen, 9 | const unsigned char *m,unsigned long long mlen, 10 | const unsigned char *sk 11 | ) 12 | { 13 | unsigned char pk[32]; 14 | unsigned char az[64]; 15 | unsigned char nonce[64]; 16 | unsigned char hram[64]; 17 | ge_p3 R; 18 | 19 | memmove(pk,sk + 32,32); 20 | 21 | crypto_hash_sha512(az,sk,32); 22 | az[0] &= 248; 23 | az[31] &= 63; 24 | az[31] |= 64; 25 | 26 | *smlen = mlen + 64; 27 | memmove(sm + 64,m,mlen); 28 | memmove(sm + 32,az + 32,32); 29 | crypto_hash_sha512(nonce,sm + 32,mlen + 32); 30 | memmove(sm + 32,pk,32); 31 | 32 | sc_reduce(nonce); 33 | ge_scalarmult_base(&R,nonce); 34 | ge_p3_tobytes(sm,&R); 35 | 36 | crypto_hash_sha512(hram,sm,mlen + 64); 37 | sc_reduce(hram); 38 | sc_muladd(sm + 32,hram,az,nonce); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/sqrtm1.h: -------------------------------------------------------------------------------- 1 | -32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482 2 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/curve25519/ed25519/tests/tests.h: -------------------------------------------------------------------------------- 1 | #ifndef __TESTS_H__ 2 | #define __TESTS_H__ 3 | 4 | /* silent = 0 : prints info+error messages to stdout, abort() on test failure 5 | * silent = 1 : returns 0 for success, anything else for failure 6 | * iterations : hardcoded known-good values are at 10000, so run at least this many 7 | */ 8 | 9 | int sha512_fast_test(int silent); 10 | int elligator_fast_test(int silent); 11 | int curvesigs_fast_test(int silent); 12 | int xeddsa_fast_test(int silent); 13 | int vxeddsa_fast_test(int silent); 14 | 15 | int curvesigs_slow_test(int silent, int iterations); 16 | int xeddsa_slow_test(int silent, int iterations); 17 | int xeddsa_to_curvesigs_slow_test(int silent, int iterations); 18 | int vxeddsa_slow_test(int silent, int iterations); 19 | 20 | int all_fast_tests(int silent); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/include_windows.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | #include 8 | 9 | #define WIN32_LEAN_AND_MEAN 10 | #define VC_EXTRALEAN 11 | 12 | #define NOGDICAPMASKS //- CC_*, LC_*, PC_*, CP_*, TC_*, RC_ 13 | #define NOVIRTUALKEYCODES //- VK_* 14 | #define NOWINMESSAGES //- WM_*, EM_*, LB_*, CB_* 15 | //#define NOWINSTYLES //- WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_* 16 | #define NOSYSMETRICS //- SM_* 17 | #define NOMENUS //- MF_* 18 | //#define NOICONS //- IDI_* 19 | #define NOKEYSTATES //- MK_* 20 | #define NOSYSCOMMANDS //- SC_* 21 | #define NORASTEROPS //- Binary and Tertiary raster ops 22 | #define NOSHOWWINDOW //- SW_* 23 | #define OEMRESOURCE //- OEM Resource values 24 | #define NOATOM //- Atom Manager routines 25 | #define NOCLIPBOARD //- Clipboard routines 26 | #define NOCOLOR //- Screen colors 27 | #define NOCTLMGR //- Control and Dialog routines 28 | #define NODRAWTEXT //- DrawText() and DT_* 29 | //#define NOGDI //- All GDI defines and routines 30 | #define NOKERNEL //- All KERNEL defines and routines 31 | //#define NOUSER //- All USER defines and routines 32 | #define NONLS //- All NLS defines and routines 33 | #define NOMB //- MB_* and MessageBox() 34 | #define NOMEMMGR //- GMEM_*, LMEM_*, GHND, LHND, associated routines 35 | #define NOMETAFILE //- typedef METAFILEPICT 36 | #define NOMINMAX //- Macros min(a,b) and max(a,b) 37 | //#define NOMSG //- typedef MSG and associated routines 38 | #define NOOPENFILE //- OpenFile(), OemToAnsi, AnsiToOem, and OF_* 39 | #define NOSCROLL //- SB_* and scrolling routines 40 | #define NOSERVICE //- All Service Controller routines, SERVICE_ equates, etc. 41 | #define NOSOUND //- Sound driver routines 42 | //#define NOTEXTMETRIC //- typedef TEXTMETRIC and associated routines 43 | #define NOWH //- SetWindowsHook and WH_* 44 | #define NOWINOFFSETS //- GWL_*, GCL_*, associated routines 45 | #define NOCOMM //- COMM driver routines 46 | #define NOKANJI //- Kanji support stuff. 47 | #define NOHELP //- Help engine interface. 48 | #define NOPROFILER //- Profiler interface. 49 | #define NODEFERWINDOWPOS //- DeferWindowPos routines 50 | #define NOMCX //- Modem Configuration Extensions 51 | 52 | #include 53 | #include 54 | #include 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/.gitignore: -------------------------------------------------------------------------------- 1 | __build__/ 2 | __pycache__ 3 | *.pyc 4 | *.pyo 5 | *.pyd 6 | *.pyz 7 | *.egg-info/ 8 | .DS_Store -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Kenneth MacKay 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/README.md: -------------------------------------------------------------------------------- 1 | micro-ecc 2 | ========== 3 | 4 | A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors. 5 | 6 | The static version of micro-ecc (ie, where the curve was selected at compile-time) can be found in the "static" branch. 7 | 8 | Features 9 | -------- 10 | 11 | * Resistant to known side-channel attacks. 12 | * Written in C, with optional GCC inline assembly for AVR, ARM and Thumb platforms. 13 | * Supports 8, 32, and 64-bit architectures. 14 | * Small code size. 15 | * No dynamic memory allocation. 16 | * Support for 5 standard curves: secp160r1, secp192r1, secp224r1, secp256r1, and secp256k1. 17 | * BSD 2-clause license. 18 | 19 | Usage Notes 20 | ----------- 21 | ### Point Representation ### 22 | Compressed points are represented in the standard format as defined in http://www.secg.org/collateral/sec1_final.pdf; uncompressed points are represented in standard format, but without the `0x04` prefix. All functions except `uECC_compress()` only accept uncompressed points; use `uECC_compress()` and `uECC_decompress()` to convert between compressed and uncompressed point representations. 23 | 24 | Private keys are represented in the standard format. 25 | 26 | ### Using the Code ### 27 | 28 | I recommend just copying (or symlink) the uECC files into your project. Then just `#include "uECC.h"` to use the micro-ecc functions. 29 | 30 | For use with Arduino, you can just create a symlink to the `uECC` directory in your Arduino `libraries` directory. You can then use uECC just like any other Arduino library (uECC should show up in the **Sketch**=>**Import Library** submenu). 31 | 32 | See uECC.h for documentation for each function. 33 | 34 | ### Compilation Notes ### 35 | 36 | * Should compile with any C/C++ compiler that supports stdint.h (this includes Visual Studio 2013). 37 | * If you want to change the defaults for any of the uECC compile-time options (such as `uECC_OPTIMIZATION_LEVEL`), you must change them in your Makefile or similar so that uECC.c is compiled with the desired values (ie, compile uECC.c with `-DuECC_OPTIMIZATION_LEVEL=3` or whatever). 38 | * When compiling for a Thumb-1 platform, you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). 39 | * When compiling for an ARM/Thumb-2 platform with `uECC_OPTIMIZATION_LEVEL` >= 3, you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). 40 | * When compiling for AVR, you must have optimizations enabled (compile with `-O1` or higher). 41 | * When building for Windows, you will need to link in the `advapi32.lib` system library. 42 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/emk_project.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | c, link, asm, utils = emk.module("c", "link", "asm", "utils") 4 | 5 | default_compile_flags = ["-fvisibility=hidden", "-Wall", "-Wextra", "-Wshadow", "-Werror", "-Wno-missing-field-initializers", "-Wno-unused-parameter", \ 6 | "-Wno-comment", "-Wno-unused", "-Wno-unknown-pragmas"] 7 | default_link_flags = [] 8 | opt_flags = {"dbg":["-g"], "std":["-O2"], "max":["-O3"], "small":["-Os"]} 9 | opt_link_flags = {"dbg":[], "std":[], "max":[], "small":[]} 10 | c_flags = ["-std=c99"] 11 | cxx_flags = ["-std=c++11", "-Wno-reorder", "-fno-rtti", "-fno-exceptions"] 12 | c_link_flags = [] 13 | cxx_link_flags = ["-fno-rtti", "-fno-exceptions"] 14 | 15 | def setup_build_dir(): 16 | build_arch = None 17 | if "arch" in emk.options: 18 | build_arch = emk.options["arch"] 19 | elif not emk.cleaning: 20 | build_arch = "osx" 21 | emk.options["arch"] = build_arch 22 | 23 | opt_level = None 24 | if "opt" in emk.options: 25 | level = emk.options["opt"] 26 | if level in opt_flags: 27 | opt_level = level 28 | else: 29 | emk.log.warning("Unknown optimization level '%s'" % (level)) 30 | elif not emk.cleaning: 31 | opt_level = "dbg" 32 | emk.options["opt"] = opt_level 33 | 34 | dirs = ["__build__"] 35 | if build_arch: 36 | dirs.append(build_arch) 37 | if opt_level: 38 | dirs.append(opt_level) 39 | emk.build_dir = os.path.join(*dirs) 40 | 41 | def setup_osx(): 42 | global c 43 | global link 44 | 45 | flags = [("-arch", "x86_64"), "-fno-common", "-Wnewline-eof"] 46 | c.flags.extend(flags) 47 | c.cxx.flags += ["-stdlib=libc++"] 48 | link.cxx.flags += ["-stdlib=libc++"] 49 | 50 | link_flags = [("-arch", "x86_64")] 51 | link.local_flags.extend(link_flags) 52 | 53 | def setup_avr(): 54 | global c 55 | global link 56 | 57 | c.compiler = c.GccCompiler("/Projects/avr-tools/bin/avr-") 58 | c.flags += ["-mmcu=atmega256rfr2", "-ffunction-sections", "-fdata-sections"] 59 | link.linker = link.GccLinker("/Projects/avr-tools/bin/avr-") 60 | link.flags += ["-mmcu=atmega256rfr2", "-mrelax", "-Wl,--gc-sections"] 61 | link.strip = True 62 | 63 | def setup_arm_thumb(): 64 | global c 65 | global link 66 | global asm 67 | global utils 68 | 69 | asm.assembler = asm.GccAssembler("/cross/arm_cortex/bin/arm-none-eabi-") 70 | c.compiler = c.GccCompiler("/cross/arm_cortex/bin/arm-none-eabi-") 71 | link.linker = link.GccLinker("/cross/arm_cortex/bin/arm-none-eabi-") 72 | 73 | c.flags.extend(["-mcpu=cortex-m0", "-mthumb", "-ffunction-sections", "-fdata-sections", "-fno-builtin-fprintf", "-fno-builtin-printf"]) 74 | c.defines["LPC11XX"] = 1 75 | 76 | link.local_flags.extend(["-mcpu=cortex-m0", "-mthumb", "-nostartfiles", "-nostdlib", "-Wl,--gc-sections"]) 77 | link.local_flags.extend(["-Tflash.lds", "-L/Projects/lpc11xx/core", "/Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o"]) 78 | link.local_syslibs += ["gcc"] 79 | link.depdirs += ["/Projects/lpc11xx/stdlib"] 80 | 81 | def do_objcopy(produces, requires): 82 | utils.call("/cross/arm_cortex/bin/arm-none-eabi-objcopy", "-O", "binary", requires[0], produces[0]) 83 | 84 | def handle_exe(path): 85 | emk.depend(path, "/Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o") 86 | emk.rule(do_objcopy, path + ".bin", path, cwd_safe=True, ex_safe=True) 87 | emk.autobuild(path + ".bin") 88 | 89 | link.exe_funcs.append(handle_exe) 90 | link.strip = True 91 | 92 | emk.recurse("/Projects/lpc11xx/core") 93 | 94 | def setup_linux_rpi(): 95 | global c 96 | global link 97 | 98 | c.compiler = c.GccCompiler("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-") 99 | link.linker = link.GccLinker("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-") 100 | 101 | c.flags.extend(["-fomit-frame-pointer"]) 102 | 103 | setup_build_dir() 104 | 105 | setup_funcs = {"osx":setup_osx, "avr":setup_avr, "arm_thumb":setup_arm_thumb, "rpi": setup_linux_rpi} 106 | 107 | if not emk.cleaning: 108 | build_arch = emk.options["arch"] 109 | opt_level = emk.options["opt"] 110 | 111 | c.flags.extend(default_compile_flags) 112 | c.flags.extend(opt_flags[opt_level]) 113 | c.c.flags.extend(c_flags) 114 | c.cxx.flags.extend(cxx_flags) 115 | link.local_flags.extend(default_link_flags) 116 | link.local_flags.extend(opt_link_flags[opt_level]) 117 | link.c.local_flags.extend(c_link_flags) 118 | link.cxx.local_flags.extend(cxx_link_flags) 119 | 120 | c.include_dirs.append("$:proj:$") 121 | 122 | if build_arch in setup_funcs: 123 | setup_funcs[build_arch]() 124 | else: 125 | raise emk.BuildError("Unknown target arch '%s'" % (build_arch)) 126 | 127 | c.defines["TARGET_ARCH_" + build_arch.upper()] = 1 128 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/emk_rules.py: -------------------------------------------------------------------------------- 1 | c, link = emk.module("c", "link") 2 | 3 | emk.subdir("test") 4 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/platform-specific.inc: -------------------------------------------------------------------------------- 1 | /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2 | 3 | #ifndef _UECC_PLATFORM_SPECIFIC_H_ 4 | #define _UECC_PLATFORM_SPECIFIC_H_ 5 | 6 | #include "types.h" 7 | 8 | #if (defined(_WIN32) || defined(_WIN64)) 9 | /* Windows */ 10 | 11 | #define WIN32_LEAN_AND_MEAN 12 | #include 13 | #include 14 | 15 | static int default_RNG(uint8_t *dest, unsigned size) { 16 | HCRYPTPROV prov; 17 | if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { 18 | return 0; 19 | } 20 | 21 | CryptGenRandom(prov, size, (BYTE *)dest); 22 | CryptReleaseContext(prov, 0); 23 | return 1; 24 | } 25 | #define default_RNG_defined 1 26 | 27 | #elif defined(unix) || defined(__linux__) || defined(__unix__) || defined(__unix) || \ 28 | (defined(__APPLE__) && defined(__MACH__)) || defined(uECC_POSIX) 29 | 30 | /* Some POSIX-like system with /dev/urandom or /dev/random. */ 31 | #include 32 | #include 33 | #include 34 | 35 | #ifndef O_CLOEXEC 36 | #define O_CLOEXEC 0 37 | #endif 38 | 39 | static int default_RNG(uint8_t *dest, unsigned size) { 40 | int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); 41 | if (fd == -1) { 42 | fd = open("/dev/random", O_RDONLY | O_CLOEXEC); 43 | if (fd == -1) { 44 | return 0; 45 | } 46 | } 47 | 48 | char *ptr = (char *)dest; 49 | size_t left = size; 50 | while (left > 0) { 51 | ssize_t bytes_read = read(fd, ptr, left); 52 | if (bytes_read <= 0) { // read failed 53 | close(fd); 54 | return 0; 55 | } 56 | left -= bytes_read; 57 | ptr += bytes_read; 58 | } 59 | 60 | close(fd); 61 | return 1; 62 | } 63 | #define default_RNG_defined 1 64 | 65 | #endif /* platform */ 66 | 67 | #endif /* _UECC_PLATFORM_SPECIFIC_H_ */ 68 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/scripts/mult_avr_extra.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | if len(sys.argv) < 2: 6 | print "Provide the integer size in bytes" 7 | sys.exit(1) 8 | 9 | size = int(sys.argv[1]) 10 | 11 | def lhi(i): 12 | return i + 2 13 | 14 | def rhi(i): 15 | return i + 6 16 | 17 | left_lo = [10, 11, 12, 13] 18 | right_lo = [14, 15, 16, 17] 19 | 20 | def llo(i): 21 | return left_lo[i] 22 | 23 | def rlo(i): 24 | return right_lo[i] 25 | 26 | def emit(line, *args): 27 | s = '"' + line + r' \n\t"' 28 | print s % args 29 | 30 | def update_low(): 31 | global left_lo 32 | global right_lo 33 | left_lo = left_lo[1:] + left_lo[:1] 34 | right_lo = right_lo[1:] + right_lo[:1] 35 | emit("ld r%s, x+", left_lo[3]) 36 | emit("ld r%s, y+", right_lo[3]) 37 | 38 | accum = [19, 20, 21] 39 | 40 | def acc(i): 41 | return accum[i] 42 | 43 | def rotate_acc(): 44 | global accum 45 | accum = accum[1:] + accum[:1] 46 | 47 | # Load high values 48 | for i in xrange(4): 49 | emit("ld r%s, x+", lhi(i)) 50 | emit("ld r%s, y+", rhi(i)) 51 | 52 | emit("sbiw r26, %s", size + 4) 53 | emit("sbiw r28, %s", size + 4) 54 | emit("sbiw r30, %s", size) 55 | 56 | # Load low values 57 | for i in xrange(4): 58 | emit("ld r%s, x+", llo(i)) 59 | emit("ld r%s, y+", rlo(i)) 60 | print "" 61 | 62 | # Compute initial triangles 63 | emit("mul r%s, r%s", lhi(0), rlo(0)) 64 | emit("mov r%s, r0", acc(0)) 65 | emit("mov r%s, r1", acc(1)) 66 | emit("ldi r%s, 0", acc(2)) 67 | emit("ld r0, z") 68 | emit("add r%s, r0", acc(0)) 69 | emit("adc r%s, r25", acc(1)) 70 | emit("mul r%s, r%s", rhi(0), llo(0)) 71 | emit("add r%s, r0", acc(0)) 72 | emit("adc r%s, r1", acc(1)) 73 | emit("adc r%s, r25", acc(2)) 74 | emit("st z+, r%s", acc(0)) 75 | print "" 76 | rotate_acc() 77 | 78 | for i in xrange(1, 4): 79 | emit("ldi r%s, 0", acc(2)) 80 | emit("ld r0, z") 81 | emit("add r%s, r0", acc(0)) 82 | emit("adc r%s, r25", acc(1)) 83 | for j in xrange(i + 1): 84 | emit("mul r%s, r%s", lhi(j), rlo(i-j)) 85 | emit("add r%s, r0", acc(0)) 86 | emit("adc r%s, r1", acc(1)) 87 | emit("adc r%s, r25", acc(2)) 88 | emit("mul r%s, r%s", rhi(j), llo(i-j)) 89 | emit("add r%s, r0", acc(0)) 90 | emit("adc r%s, r1", acc(1)) 91 | emit("adc r%s, r25", acc(2)) 92 | emit("st z+, r%s", acc(0)) 93 | print "" 94 | rotate_acc() 95 | 96 | # Compute rows overlapping old block 97 | for i in xrange(4, size): 98 | emit("ldi r%s, 0", acc(2)) 99 | emit("ld r0, z") 100 | emit("add r%s, r0", acc(0)) 101 | emit("adc r%s, r25", acc(1)) 102 | update_low() 103 | for j in xrange(4): 104 | emit("mul r%s, r%s", lhi(j), rlo(3-j)) 105 | emit("add r%s, r0", acc(0)) 106 | emit("adc r%s, r1", acc(1)) 107 | emit("adc r%s, r25", acc(2)) 108 | emit("mul r%s, r%s", rhi(j), llo(3-j)) 109 | emit("add r%s, r0", acc(0)) 110 | emit("adc r%s, r1", acc(1)) 111 | emit("adc r%s, r25", acc(2)) 112 | emit("st z+, r%s", acc(0)) 113 | print "" 114 | rotate_acc() 115 | 116 | # Compute new triangle 117 | left_combined = [llo(1), llo(2), llo(3), lhi(0), lhi(1), lhi(2), lhi(3)] 118 | right_combined = [rlo(1), rlo(2), rlo(3), rhi(0), rhi(1), rhi(2), rhi(3)] 119 | 120 | def left(i): 121 | return left_combined[i] 122 | 123 | def right(i): 124 | return right_combined[i] 125 | 126 | for i in xrange(6): 127 | emit("ldi r%s, 0", acc(2)) 128 | for j in xrange(7 - i): 129 | emit("mul r%s, r%s", left(i+j), right(6-j)) 130 | emit("add r%s, r0", acc(0)) 131 | emit("adc r%s, r1", acc(1)) 132 | emit("adc r%s, r25", acc(2)) 133 | emit("st z+, r%s", acc(0)) 134 | print "" 135 | rotate_acc() 136 | 137 | emit("mul r%s, r%s", left(6), right(6)) 138 | emit("add r%s, r0", acc(0)) 139 | emit("adc r%s, r1", acc(1)) 140 | emit("st z+, r%s", acc(0)) 141 | emit("st z+, r%s", acc(1)) 142 | emit("adiw r26, 4") 143 | emit("adiw r28, 4") 144 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/test/ecc_test/ecc_test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern "C" { 4 | 5 | static int RNG(uint8_t *dest, unsigned size) { 6 | // Use the least-significant bits from the ADC for an unconnected pin (or connected to a source of 7 | // random noise). This can take a long time to generate random data if the result of analogRead(0) 8 | // doesn't change very frequently. 9 | while (size) { 10 | uint8_t val = 0; 11 | for (unsigned i = 0; i < 8; ++i) { 12 | int init = analogRead(0); 13 | int count = 0; 14 | while (analogRead(0) == init) { 15 | ++count; 16 | } 17 | 18 | if (count == 0) { 19 | val = (val << 1) | (init & 0x01); 20 | } else { 21 | val = (val << 1) | (count & 0x01); 22 | } 23 | } 24 | *dest = val; 25 | ++dest; 26 | --size; 27 | } 28 | // NOTE: it would be a good idea to hash the resulting random data using SHA-256 or similar. 29 | return 1; 30 | } 31 | 32 | } // extern "C" 33 | 34 | void setup() { 35 | Serial.begin(115200); 36 | Serial.print("Testing ecc\n"); 37 | uECC_set_rng(&RNG); 38 | } 39 | 40 | void loop() { 41 | const struct uECC_Curve_t * curve = uECC_secp160r1(); 42 | uint8_t private1[21]; 43 | uint8_t private2[21]; 44 | 45 | uint8_t public1[40]; 46 | uint8_t public2[40]; 47 | 48 | uint8_t secret1[20]; 49 | uint8_t secret2[20]; 50 | 51 | unsigned long a = millis(); 52 | uECC_make_key(public1, private1, curve); 53 | unsigned long b = millis(); 54 | 55 | Serial.print("Made key 1 in "); Serial.println(b-a); 56 | a = millis(); 57 | uECC_make_key(public2, private2, curve); 58 | b = millis(); 59 | Serial.print("Made key 2 in "); Serial.println(b-a); 60 | 61 | a = millis(); 62 | int r = uECC_shared_secret(public2, private1, secret1, curve); 63 | b = millis(); 64 | Serial.print("Shared secret 1 in "); Serial.println(b-a); 65 | if (!r) { 66 | Serial.print("shared_secret() failed (1)\n"); 67 | return; 68 | } 69 | 70 | a = millis(); 71 | r = uECC_shared_secret(public1, private2, secret2, curve); 72 | b = millis(); 73 | Serial.print("Shared secret 2 in "); Serial.println(b-a); 74 | if (!r) { 75 | Serial.print("shared_secret() failed (2)\n"); 76 | return; 77 | } 78 | 79 | if (memcmp(secret1, secret2, 20) != 0) { 80 | Serial.print("Shared secrets are not identical!\n"); 81 | } else { 82 | Serial.print("Shared secrets are identical\n"); 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/test/emk_rules.py: -------------------------------------------------------------------------------- 1 | c, link = emk.module("c", "link") 2 | link.depdirs += [ 3 | "$:proj:$" 4 | ] 5 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/test/test_compress.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2 | 3 | #include "uECC.h" 4 | 5 | #include 6 | #include 7 | 8 | #ifndef uECC_TEST_NUMBER_OF_ITERATIONS 9 | #define uECC_TEST_NUMBER_OF_ITERATIONS 256 10 | #endif 11 | 12 | void vli_print(char *str, uint8_t *vli, unsigned int size) { 13 | printf("%s ", str); 14 | for(unsigned i=0; i 6 | #include 7 | 8 | void vli_print(char *str, uint8_t *vli, unsigned int size) { 9 | printf("%s ", str); 10 | for(unsigned i=0; i 6 | #include 7 | 8 | void vli_print(uint8_t *vli, unsigned int size) { 9 | for(unsigned i=0; i 6 | #include 7 | 8 | int main() { 9 | int i, c; 10 | uint8_t private[32] = {0}; 11 | uint8_t public[64] = {0}; 12 | uint8_t hash[32] = {0}; 13 | uint8_t sig[64] = {0}; 14 | 15 | const struct uECC_Curve_t * curves[5]; 16 | int num_curves = 0; 17 | #if uECC_SUPPORTS_secp160r1 18 | curves[num_curves++] = uECC_secp160r1(); 19 | #endif 20 | #if uECC_SUPPORTS_secp192r1 21 | curves[num_curves++] = uECC_secp192r1(); 22 | #endif 23 | #if uECC_SUPPORTS_secp224r1 24 | curves[num_curves++] = uECC_secp224r1(); 25 | #endif 26 | #if uECC_SUPPORTS_secp256r1 27 | curves[num_curves++] = uECC_secp256r1(); 28 | #endif 29 | #if uECC_SUPPORTS_secp256k1 30 | curves[num_curves++] = uECC_secp256k1(); 31 | #endif 32 | 33 | printf("Testing 256 signatures\n"); 34 | for (c = 0; c < num_curves; ++c) { 35 | for (i = 0; i < 256; ++i) { 36 | printf("."); 37 | fflush(stdout); 38 | 39 | if (!uECC_make_key(public, private, curves[c])) { 40 | printf("uECC_make_key() failed\n"); 41 | return 1; 42 | } 43 | memcpy(hash, public, sizeof(hash)); 44 | 45 | if (!uECC_sign(private, hash, sizeof(hash), sig, curves[c])) { 46 | printf("uECC_sign() failed\n"); 47 | return 1; 48 | } 49 | 50 | if (!uECC_verify(public, hash, sizeof(hash), sig, curves[c])) { 51 | printf("uECC_verify() failed\n"); 52 | return 1; 53 | } 54 | } 55 | printf("\n"); 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/test/test_ecdsa_deterministic.c.example: -------------------------------------------------------------------------------- 1 | /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2 | 3 | #include "uECC.h" 4 | 5 | #include 6 | #include 7 | 8 | #define SHA256_BLOCK_LENGTH 64 9 | #define SHA256_DIGEST_LENGTH 32 10 | 11 | typedef struct SHA256_CTX { 12 | uint32_t state[8]; 13 | uint64_t bitcount; 14 | uint8_t buffer[SHA256_BLOCK_LENGTH]; 15 | } SHA256_CTX; 16 | 17 | extern void SHA256_Init(SHA256_CTX *ctx); 18 | extern void SHA256_Update(SHA256_CTX *ctx, const uint8_t *message, size_t message_size); 19 | extern void SHA256_Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *ctx); 20 | 21 | typedef struct SHA256_HashContext { 22 | uECC_HashContext uECC; 23 | SHA256_CTX ctx; 24 | } SHA256_HashContext; 25 | 26 | static void init_SHA256(const uECC_HashContext *base) { 27 | SHA256_HashContext *context = (SHA256_HashContext *)base; 28 | SHA256_Init(&context->ctx); 29 | } 30 | 31 | static void update_SHA256(const uECC_HashContext *base, 32 | const uint8_t *message, 33 | unsigned message_size) { 34 | SHA256_HashContext *context = (SHA256_HashContext *)base; 35 | SHA256_Update(&context->ctx, message, message_size); 36 | } 37 | 38 | static void finish_SHA256(const uECC_HashContext *base, uint8_t *hash_result) { 39 | SHA256_HashContext *context = (SHA256_HashContext *)base; 40 | SHA256_Final(hash_result, &context->ctx); 41 | } 42 | 43 | int main() { 44 | int i, c; 45 | uint8_t private[32] = {0}; 46 | uint8_t public[64] = {0}; 47 | uint8_t hash[32] = {0}; 48 | uint8_t sig[64] = {0}; 49 | 50 | uint8_t tmp[2 * SHA256_DIGEST_LENGTH + SHA256_BLOCK_LENGTH]; 51 | SHA256_HashContext ctx = {{ 52 | &init_SHA256, 53 | &update_SHA256, 54 | &finish_SHA256, 55 | SHA256_BLOCK_LENGTH, 56 | SHA256_DIGEST_LENGTH, 57 | tmp 58 | }}; 59 | 60 | const struct uECC_Curve_t * curves[5]; 61 | curves[0] = uECC_secp160r1(); 62 | curves[1] = uECC_secp192r1(); 63 | curves[2] = uECC_secp224r1(); 64 | curves[3] = uECC_secp256r1(); 65 | curves[4] = uECC_secp256k1(); 66 | 67 | printf("Testing 256 signatures\n"); 68 | for (c = 0; c < 5; ++c) { 69 | for (i = 0; i < 256; ++i) { 70 | printf("."); 71 | fflush(stdout); 72 | 73 | if (!uECC_make_key(public, private, curves[c])) { 74 | printf("uECC_make_key() failed\n"); 75 | return 1; 76 | } 77 | memcpy(hash, public, sizeof(hash)); 78 | 79 | if (!uECC_sign_deterministic(private, hash, sizeof(hash), &ctx.uECC, sig, curves[c])) { 80 | printf("uECC_sign() failed\n"); 81 | return 1; 82 | } 83 | 84 | if (!uECC_verify(public, hash, sizeof(hash), sig, curves[c])) { 85 | printf("uECC_verify() failed\n"); 86 | return 1; 87 | } 88 | } 89 | printf("\n"); 90 | } 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/mico-ecc/types.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2 | 3 | #ifndef _UECC_TYPES_H_ 4 | #define _UECC_TYPES_H_ 5 | 6 | #ifndef uECC_PLATFORM 7 | #if __AVR__ 8 | #define uECC_PLATFORM uECC_avr 9 | #elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */ 10 | #define uECC_PLATFORM uECC_arm_thumb2 11 | #elif defined(__thumb__) 12 | #define uECC_PLATFORM uECC_arm_thumb 13 | #elif defined(__arm__) || defined(_M_ARM) 14 | #define uECC_PLATFORM uECC_arm 15 | #elif defined(__aarch64__) 16 | #define uECC_PLATFORM uECC_arm64 17 | #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__) 18 | #define uECC_PLATFORM uECC_x86 19 | #elif defined(__amd64__) || defined(_M_X64) 20 | #define uECC_PLATFORM uECC_x86_64 21 | #else 22 | #define uECC_PLATFORM uECC_arch_other 23 | #endif 24 | #endif 25 | 26 | #ifndef uECC_ARM_USE_UMAAL 27 | #if (uECC_PLATFORM == uECC_arm) && (__ARM_ARCH >= 6) 28 | #define uECC_ARM_USE_UMAAL 1 29 | #elif (uECC_PLATFORM == uECC_arm_thumb2) && (__ARM_ARCH >= 6) && !__ARM_ARCH_7M__ 30 | #define uECC_ARM_USE_UMAAL 1 31 | #else 32 | #define uECC_ARM_USE_UMAAL 0 33 | #endif 34 | #endif 35 | 36 | #ifndef uECC_WORD_SIZE 37 | #if uECC_PLATFORM == uECC_avr 38 | #define uECC_WORD_SIZE 1 39 | #elif (uECC_PLATFORM == uECC_x86_64 || uECC_PLATFORM == uECC_arm64) 40 | #define uECC_WORD_SIZE 8 41 | #else 42 | #define uECC_WORD_SIZE 4 43 | #endif 44 | #endif 45 | 46 | #if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8) 47 | #error "Unsupported value for uECC_WORD_SIZE" 48 | #endif 49 | 50 | #if ((uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) 51 | #pragma message ("uECC_WORD_SIZE must be 1 for AVR") 52 | #undef uECC_WORD_SIZE 53 | #define uECC_WORD_SIZE 1 54 | #endif 55 | 56 | #if ((uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ 57 | uECC_PLATFORM == uECC_arm_thumb2) && \ 58 | (uECC_WORD_SIZE != 4)) 59 | #pragma message ("uECC_WORD_SIZE must be 4 for ARM") 60 | #undef uECC_WORD_SIZE 61 | #define uECC_WORD_SIZE 4 62 | #endif 63 | 64 | #if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) 65 | #define SUPPORTS_INT128 1 66 | #else 67 | #define SUPPORTS_INT128 0 68 | #endif 69 | 70 | typedef int8_t wordcount_t; 71 | typedef int16_t bitcount_t; 72 | typedef int8_t cmpresult_t; 73 | 74 | #if (uECC_WORD_SIZE == 1) 75 | 76 | typedef uint8_t uECC_word_t; 77 | typedef uint16_t uECC_dword_t; 78 | 79 | #define HIGH_BIT_SET 0x80 80 | #define uECC_WORD_BITS 8 81 | #define uECC_WORD_BITS_SHIFT 3 82 | #define uECC_WORD_BITS_MASK 0x07 83 | 84 | #elif (uECC_WORD_SIZE == 4) 85 | 86 | typedef uint32_t uECC_word_t; 87 | typedef uint64_t uECC_dword_t; 88 | 89 | #define HIGH_BIT_SET 0x80000000 90 | #define uECC_WORD_BITS 32 91 | #define uECC_WORD_BITS_SHIFT 5 92 | #define uECC_WORD_BITS_MASK 0x01F 93 | 94 | #elif (uECC_WORD_SIZE == 8) 95 | 96 | typedef uint64_t uECC_word_t; 97 | #if SUPPORTS_INT128 98 | typedef unsigned __int128 uECC_dword_t; 99 | #endif 100 | 101 | #define HIGH_BIT_SET 0x8000000000000000ull 102 | #define uECC_WORD_BITS 64 103 | #define uECC_WORD_BITS_SHIFT 6 104 | #define uECC_WORD_BITS_MASK 0x03F 105 | 106 | #endif /* uECC_WORD_SIZE */ 107 | 108 | #endif /* _UECC_TYPES_H_ */ 109 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/sec_rnd.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | #include "include_windows.h" 10 | #include 11 | #include 12 | 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | int secure_random(uint8_t* rnd, uint32_t sz_rnd) 16 | { 17 | BOOL b; 18 | HCRYPTPROV hCryptProvider; 19 | 20 | if (!CryptAcquireContextW(&hCryptProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) 21 | return 0; 22 | 23 | b = CryptGenRandom(hCryptProvider, sz_rnd, rnd); 24 | CryptReleaseContext(hCryptProvider, 0); 25 | 26 | if (b == FALSE) 27 | return 0; 28 | 29 | return 1; 30 | } 31 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/sec_rnd.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | #include "cryptovium.h" 10 | #include "include_windows.h" 11 | #include 12 | #include 13 | 14 | 15 | int secure_random(uint8_t* rnd, uint32_t sz_rnd); 16 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/sha256.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | #include "sha256.h" 10 | #include "zeroize.h" 11 | 12 | 13 | typedef struct 14 | { 15 | BLOBHEADER hdr; 16 | DWORD keyLength; 17 | BYTE key[128]; 18 | } keydata_t; 19 | 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | void sha256_free(sha256_context* ctx) 23 | { 24 | if (ctx->hCryptProv) 25 | { 26 | CryptReleaseContext(ctx->hCryptProv, 0); 27 | ctx->hCryptProv = 0; 28 | } 29 | 30 | if (ctx->hHash) 31 | { 32 | CryptDestroyHash(ctx->hHash); 33 | ctx->hHash = 0; 34 | } 35 | 36 | if (ctx->hKey) 37 | { 38 | CryptDestroyKey(ctx->hKey); 39 | ctx->hKey = 0; 40 | } 41 | } 42 | 43 | //////////////////////////////////////////////////////////////////////////////// 44 | int sha256_init(sha256_context* ctx) 45 | { 46 | memset(ctx, 0, sizeof(sha256_context)); 47 | 48 | if (!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) 49 | return 0; 50 | 51 | if (!CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash)) 52 | { 53 | sha256_free(ctx); 54 | return 0; 55 | } 56 | 57 | return 1; 58 | } 59 | 60 | //////////////////////////////////////////////////////////////////////////////// 61 | int sha256_update(sha256_context* ctx, const uint8_t* input, size_t ilen) 62 | { 63 | if (!CryptHashData(ctx->hHash, input, ilen, 0)) 64 | return 0; 65 | 66 | return 1; 67 | } 68 | 69 | //////////////////////////////////////////////////////////////////////////////// 70 | int sha256_finish(sha256_context* ctx, uint8_t output[SHA256_HASH_SIZE]) 71 | { 72 | DWORD dw; 73 | 74 | dw = SHA256_HASH_SIZE; 75 | if (!CryptGetHashParam(ctx->hHash, HP_HASHVAL, output, &dw, 0)) 76 | return 0; 77 | 78 | sha256_free(ctx); 79 | 80 | return 1; 81 | } 82 | 83 | //////////////////////////////////////////////////////////////////////////////// 84 | int sha256(const uint8_t* input, size_t ilen, uint8_t output[SHA256_HASH_SIZE]) 85 | { 86 | sha256_context ctx; 87 | 88 | if (!sha256_init(&ctx)) return 0; 89 | if (!sha256_update(&ctx, input, ilen)) return 0; 90 | if (!sha256_finish(&ctx, output)) return 0; 91 | 92 | return 1; 93 | } 94 | 95 | 96 | 97 | 98 | //////////////////////////////////////////////////////////////////////////////// 99 | int sha256_hmac_init(sha256_context* ctx, const uint8_t* key, size_t keylen) 100 | { 101 | keydata_t kd; 102 | HMAC_INFO hmacInfo; 103 | 104 | if (keylen > sizeof(kd.key)) return 0; 105 | 106 | memset(ctx, 0, sizeof(sha256_context)); 107 | 108 | if (!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) 109 | return 0; 110 | 111 | // import the raw secret as the HMAC key 112 | kd.hdr.bType = PLAINTEXTKEYBLOB; 113 | kd.hdr.bVersion = CUR_BLOB_VERSION; 114 | kd.hdr.reserved = 0; 115 | kd.hdr.aiKeyAlg = CALG_RC2; // ugh. I hate crypto api. this allows importing an HMAC key. 116 | kd.keyLength = keylen; 117 | memcpy(kd.key, key, keylen); 118 | 119 | if (!CryptImportKey(ctx->hCryptProv, (BYTE*)&kd, sizeof(kd), 0, CRYPT_IPSEC_HMAC_KEY, &ctx->hKey)) 120 | { 121 | sha256_free(ctx); 122 | return 0; 123 | } 124 | 125 | zeroize(&kd, sizeof(kd)); 126 | 127 | if (!CryptCreateHash(ctx->hCryptProv, CALG_HMAC, ctx->hKey, 0, &ctx->hHash)) 128 | { 129 | sha256_free(ctx); 130 | return 0; 131 | } 132 | 133 | memset(&hmacInfo, 0, sizeof(hmacInfo)); 134 | hmacInfo.HashAlgid = CALG_SHA_256; 135 | 136 | if (!CryptSetHashParam(ctx->hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0)) 137 | { 138 | sha256_free(ctx); 139 | return 0; 140 | } 141 | 142 | return 1; 143 | } 144 | 145 | //////////////////////////////////////////////////////////////////////////////// 146 | int sha256_hmac_update(sha256_context* ctx, const uint8_t* input, size_t ilen) 147 | { 148 | return sha256_update(ctx, input, ilen); 149 | } 150 | 151 | //////////////////////////////////////////////////////////////////////////////// 152 | int sha256_hmac_finish(sha256_context* ctx, uint8_t output[SHA256_HASH_SIZE]) 153 | { 154 | sha256_finish(ctx, output); 155 | sha256_free(ctx); 156 | 157 | return 1; 158 | } 159 | 160 | //////////////////////////////////////////////////////////////////////////////// 161 | int sha256_hmac(const uint8_t* key, size_t keylen, const uint8_t* input, size_t ilen, uint8_t output[SHA256_HASH_SIZE]) 162 | { 163 | sha256_context ctx; 164 | 165 | if (!sha256_hmac_init(&ctx, key, keylen)) return 0; 166 | if (!sha256_update(&ctx, input, ilen)) return 0; 167 | if (!sha256_finish(&ctx, output)) return 0; 168 | 169 | return 1; 170 | } 171 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/sha256.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #ifndef _SHA256_H_ 11 | #define _SHA256_H_ 12 | 13 | 14 | #define SHA256_HASH_SIZE (32) 15 | 16 | #include "include_windows.h" 17 | #include 18 | 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef struct 25 | { 26 | HCRYPTPROV hCryptProv; 27 | HCRYPTHASH hHash; 28 | HCRYPTKEY hKey; 29 | } 30 | sha256_context; 31 | 32 | 33 | int sha256_init(sha256_context* ctx); 34 | int sha256_update(sha256_context* ctx, const uint8_t* input, size_t ilen); 35 | int sha256_finish(sha256_context* ctx, uint8_t output[SHA256_HASH_SIZE]); 36 | int sha256(const uint8_t* input, size_t ilen, uint8_t output[SHA256_HASH_SIZE]); 37 | 38 | int sha256_hmac_init(sha256_context* ctx, const uint8_t* key, size_t keylen); 39 | int sha256_hmac_update(sha256_context* ctx, const uint8_t* input, size_t ilen); 40 | int sha256_hmac_finish(sha256_context* ctx, uint8_t output[SHA256_HASH_SIZE]); 41 | int sha256_hmac(const uint8_t* key, size_t keylen, const uint8_t* input, size_t ilen, uint8_t output[SHA256_HASH_SIZE]); 42 | 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif // _SHA256_H_ 49 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/sha512.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | #include "sha512.h" 10 | 11 | 12 | //////////////////////////////////////////////////////////////////////////////// 13 | void sha512_free(sha512_context* ctx) 14 | { 15 | if (ctx->hCryptProv) 16 | { 17 | CryptReleaseContext(ctx->hCryptProv, 0); 18 | ctx->hCryptProv = 0; 19 | } 20 | 21 | if (ctx->hHash) 22 | { 23 | CryptDestroyHash(ctx->hHash); 24 | ctx->hHash = 0; 25 | } 26 | } 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | int sha512_init(sha512_context* ctx) 30 | { 31 | memset(ctx, 0, sizeof(sha512_context)); 32 | 33 | if (!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) 34 | return 0; 35 | 36 | if (!CryptCreateHash(ctx->hCryptProv, CALG_SHA_512, 0, 0, &ctx->hHash)) 37 | { 38 | sha512_free(ctx); 39 | return 0; 40 | } 41 | 42 | return 1; 43 | } 44 | 45 | //////////////////////////////////////////////////////////////////////////////// 46 | int sha512_update(sha512_context* ctx, const uint8_t* input, size_t ilen) 47 | { 48 | if (!CryptHashData(ctx->hHash, input, ilen, 0)) 49 | return 0; 50 | 51 | return 1; 52 | } 53 | 54 | //////////////////////////////////////////////////////////////////////////////// 55 | int sha512_finish(sha512_context* ctx, uint8_t output[SHA512_HASH_SIZE]) 56 | { 57 | DWORD dw; 58 | 59 | dw = SHA512_HASH_SIZE; 60 | if (!CryptGetHashParam(ctx->hHash, HP_HASHVAL, output, &dw, 0)) 61 | return 0; 62 | 63 | sha512_free(ctx); 64 | 65 | return 1; 66 | } 67 | 68 | //////////////////////////////////////////////////////////////////////////////// 69 | int sha512(const uint8_t* input, size_t ilen, uint8_t output[SHA512_HASH_SIZE]) 70 | { 71 | sha512_context ctx; 72 | 73 | if (!sha512_init(&ctx)) return 0; 74 | if (!sha512_update(&ctx, input, ilen)) return 0; 75 | if (!sha512_finish(&ctx, output)) return 0; 76 | 77 | return 1; 78 | } 79 | -------------------------------------------------------------------------------- /src/cryptovium/platform/windows/sha512.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #ifndef _SHA512_H_ 11 | #define _SHA512_H_ 12 | 13 | 14 | #define SHA512_HASH_SIZE (64) 15 | 16 | #include "include_windows.h" 17 | #include 18 | 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef struct 25 | { 26 | HCRYPTPROV hCryptProv; 27 | HCRYPTHASH hHash; 28 | } 29 | sha512_context; 30 | 31 | 32 | int sha512_init(sha512_context* ctx); 33 | int sha512_update(sha512_context* ctx, const uint8_t* input, size_t ilen); 34 | int sha512_finish(sha512_context* ctx, uint8_t output[SHA512_HASH_SIZE]); 35 | int sha512(const uint8_t* input, size_t ilen, uint8_t output[SHA512_HASH_SIZE]); 36 | 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif // _SHA512_H_ 43 | -------------------------------------------------------------------------------- /src/cryptovium/platform/zeroize.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 01/13/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #include "zeroize.h" 11 | #include 12 | 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | void zeroize(void *v, uint32_t n) 16 | { 17 | // this should not get optimized away by the compiler 18 | volatile uint8_t* p; 19 | 20 | p = v; 21 | while (n--) { *p++ = 0; } 22 | } 23 | 24 | //////////////////////////////////////////////////////////////////////////////// 25 | void zeroize_stack(void) 26 | { 27 | uint8_t z[ZEROIZE_STACK_SIZE]; 28 | 29 | zeroize(z, ZEROIZE_STACK_SIZE); 30 | } 31 | -------------------------------------------------------------------------------- /src/cryptovium/platform/zeroize.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2016 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 01/13/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #ifndef _ZEROIZE_H_ 11 | #define _ZEROIZE_H_ 12 | 13 | #define ZEROIZE_STACK_SIZE 1024 14 | 15 | #include 16 | 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | 23 | void zeroize(void *v, uint32_t n); 24 | void zeroize_stack(void); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif // _ZEROIZE_H_ 31 | -------------------------------------------------------------------------------- /src/cryptovium/unit_tests/cryptovium_tests.c: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/12/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #include "cryptovium.h" 11 | #include "cryptovium_tests.h" 12 | #include 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | cvm_error_t cvm_ut_all() 16 | { 17 | cvm_error_t ret; 18 | 19 | // execute SHA unit tests 20 | ret = cvm_ut_sha256_v1(); if (ret != CVM_ERR_NONE) return ret; 21 | ret = cvm_ut_sha256_v2(); if (ret != CVM_ERR_NONE) return ret; 22 | ret = cvm_ut_sha256_v3(); if (ret != CVM_ERR_NONE) return ret; 23 | ret = cvm_ut_sha256_v1_inc(); if (ret != CVM_ERR_NONE) return ret; 24 | ret = cvm_ut_sha256_v2_inc(); if (ret != CVM_ERR_NONE) return ret; 25 | ret = cvm_ut_sha256_v3_inc(); if (ret != CVM_ERR_NONE) return ret; 26 | ret = cvm_ut_sha512_v1(); if (ret != CVM_ERR_NONE) return ret; 27 | ret = cvm_ut_sha512_v2(); if (ret != CVM_ERR_NONE) return ret; 28 | ret = cvm_ut_sha512_v3(); if (ret != CVM_ERR_NONE) return ret; 29 | ret = cvm_ut_sha512_v1_inc(); if (ret != CVM_ERR_NONE) return ret; 30 | ret = cvm_ut_sha512_v2_inc(); if (ret != CVM_ERR_NONE) return ret; 31 | ret = cvm_ut_sha512_v3_inc(); if (ret != CVM_ERR_NONE) return ret; 32 | ret = cvm_ut_hmac_sha256_v1(); if (ret != CVM_ERR_NONE) return ret; 33 | ret = cvm_ut_hmac_sha256_v2(); if (ret != CVM_ERR_NONE) return ret; 34 | ret = cvm_ut_hmac_sha256_v3(); if (ret != CVM_ERR_NONE) return ret; 35 | ret = cvm_ut_hmac_sha256_v4(); if (ret != CVM_ERR_NONE) return ret; 36 | ret = cvm_ut_hmac_sha256_v1_inc(); if (ret != CVM_ERR_NONE) return ret; 37 | ret = cvm_ut_hmac_sha256_v2_inc(); if (ret != CVM_ERR_NONE) return ret; 38 | ret = cvm_ut_hmac_sha256_v3_inc(); if (ret != CVM_ERR_NONE) return ret; 39 | ret = cvm_ut_hmac_sha256_v4_inc(); if (ret != CVM_ERR_NONE) return ret; 40 | 41 | // execute fidou2f unit tests 42 | ret = cvm_ut_fidou2f_register(); if (ret != CVM_ERR_NONE) return ret; 43 | ret = cvm_ut_fidou2f_authenticate(); if (ret != CVM_ERR_NONE) return ret; 44 | 45 | return CVM_ERR_NONE; 46 | } 47 | 48 | 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | void _dump_buffer(uint8_t* buffer, uint32_t sz_buffer) 52 | { 53 | for (uint32_t i = 0; i < sz_buffer; ++i) 54 | printf("%02x", buffer[i]); 55 | 56 | printf("\n"); 57 | } 58 | 59 | //////////////////////////////////////////////////////////////////////////////// 60 | cvm_error_t _cvm_ut_dump_error(cvm_error_t err, uint8_t* buffer, uint32_t sz_buffer) 61 | { 62 | cvm_regs_t* pregs; 63 | 64 | switch (err) 65 | { 66 | case CVM_ERR_NONE: 67 | printf("OK\n"); 68 | break; 69 | case CVM_ERR_END_OF_STREAM: 70 | printf("error: CVM_ERR_END_OF_STREAM\n"); 71 | break; 72 | case CVM_ERR_INVALID_REG: 73 | printf("error: CVM_ERR_INVALID_REG\n"); 74 | break; 75 | case CVM_ERR_INVALID_OPERAND: 76 | printf("error: CVM_ERR_INVALID_OPERAND\n"); 77 | break; 78 | case CVM_ERR_INVALID_OPERAND_LENGTH: 79 | printf("error: CVM_ERR_INVALID_OPERAND_LENGTH\n"); 80 | break; 81 | case CVM_ERR_ENTROPY_SOURCE_FAILED: 82 | printf("error: CVM_ERR_ENTROPY_SOURCE_FAILED\n"); 83 | break; 84 | case CVM_ERR_ZERO_DATA: 85 | printf("error: CVM_ERR_ZERO_DATA\n"); 86 | break; 87 | case CVM_ERR_NO_CONTEXT: 88 | printf("error: CVM_ERR_NO_CONTEXT\n"); 89 | break; 90 | case CVM_ERR_NOT_IMPLEMENTED: 91 | printf("error: CVM_ERR_NOT_IMPLEMENTED\n"); 92 | break; 93 | case CVM_ERR_BUFFER_OVERFLOW: 94 | printf("error: CVM_ERR_BUFFER_OVERFLOW\n"); 95 | break; 96 | case CVM_ERR_COMPARE_FAILED: 97 | printf("error: CVM_ERR_EQUALS_FAILED\n"); 98 | break; 99 | case CVM_ERR_SIGNATURE_VERIFY_FAILED: 100 | printf("error: CVM_ERR_VERIFY_SIGNATURE_FAILED\n"); 101 | break; 102 | case CVM_ERR_NOT_INITIALIZED: 103 | printf("error: CVM_ERR_NOT_INITIALIZED\n"); 104 | break; 105 | case CVM_ERR_IMM_EXT_OVERFLOW: 106 | printf("error: CVM_ERR_IMM_EXT_OVERFLOW\n"); 107 | break; 108 | case CVM_ERR_INVALID_IMM_EXT: 109 | printf("error: CVM_ERR_INVALID_IMM_EXT\n"); 110 | break; 111 | default: 112 | printf("error: ***UNKNOWN_ERROR***\n"); 113 | break; 114 | } 115 | 116 | printf("REGS:\n"); 117 | pregs = cvm_get_regs(); 118 | printf("a = "); _dump_buffer(pregs->regs32.a, 32); 119 | printf("b = "); _dump_buffer(pregs->regs32.b, 32); 120 | printf("c = "); _dump_buffer(pregs->regs32.c, 32); 121 | printf("d = "); _dump_buffer(pregs->regs32.d, 32); 122 | printf("e = "); _dump_buffer(pregs->regs32.e, 32); 123 | printf("f = "); _dump_buffer(pregs->regs32.f, 32); 124 | printf("g = "); _dump_buffer(pregs->regs32.g, 32); 125 | printf("h = "); _dump_buffer(pregs->regs32.h, 32); 126 | printf("\n"); 127 | 128 | if (sz_buffer > 0) 129 | { 130 | printf("BUFFER (size=%i):\n", sz_buffer); 131 | _dump_buffer(buffer, sz_buffer); 132 | } 133 | 134 | printf("\n"); 135 | return err; 136 | } 137 | -------------------------------------------------------------------------------- /src/cryptovium/unit_tests/cryptovium_tests.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 3 | // 4 | // Author: Jeff Cesnik 5 | // Last Modified: 02/10/2017 6 | // 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | #ifndef _CRYPTOVIUM_TESTS_H_ 11 | #define _CRYPTOVIUM_TESTS_H_ 12 | 13 | #include "cryptovium.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | 20 | // EXECUTE ALL TESTS 21 | cvm_error_t cvm_ut_all(void); 22 | 23 | 24 | cvm_error_t _cvm_ut_dump_error(cvm_error_t err, uint8_t* buffer, uint32_t sz_buffer); 25 | 26 | // SHA unit tests 27 | cvm_error_t cvm_ut_sha256_v1(void); 28 | cvm_error_t cvm_ut_sha256_v2(void); 29 | cvm_error_t cvm_ut_sha256_v3(void); 30 | cvm_error_t cvm_ut_sha256_v1_inc(void); 31 | cvm_error_t cvm_ut_sha256_v2_inc(void); 32 | cvm_error_t cvm_ut_sha256_v3_inc(void); 33 | cvm_error_t cvm_ut_sha512_v1(void); 34 | cvm_error_t cvm_ut_sha512_v2(void); 35 | cvm_error_t cvm_ut_sha512_v3(void); 36 | cvm_error_t cvm_ut_sha512_v1_inc(void); 37 | cvm_error_t cvm_ut_sha512_v2_inc(void); 38 | cvm_error_t cvm_ut_sha512_v3_inc(void); 39 | cvm_error_t cvm_ut_hmac_sha256_v1(void); 40 | cvm_error_t cvm_ut_hmac_sha256_v2(void); 41 | cvm_error_t cvm_ut_hmac_sha256_v3(void); 42 | cvm_error_t cvm_ut_hmac_sha256_v4(void); 43 | cvm_error_t cvm_ut_hmac_sha256_v1_inc(void); 44 | cvm_error_t cvm_ut_hmac_sha256_v2_inc(void); 45 | cvm_error_t cvm_ut_hmac_sha256_v3_inc(void); 46 | cvm_error_t cvm_ut_hmac_sha256_v4_inc(void); 47 | 48 | // FIDO unit tests 49 | cvm_error_t cvm_ut_fidou2f_register(void); 50 | cvm_error_t cvm_ut_fidou2f_authenticate(void); 51 | 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif // _CRYPTOVIUM_TESTS_H_ 58 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Copyright (C) 2017 Lightfactor, LLC. All rights reserved. 4 | // 5 | // Author: Jeff Cesnik 6 | // Last Modified: 02/12/2017 7 | // 8 | //////////////////////////////////////////////////////////////////////////////// 9 | 10 | #include "compare_ct.h" 11 | #include "cryptovium.h" 12 | #include "cryptovium_tests.h" 13 | #include 14 | 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | int main() 18 | { 19 | printf("\nCryptovium v1.0\n\n"); 20 | 21 | cvm_init(); 22 | 23 | // execute unit tests 24 | cvm_ut_all(); 25 | 26 | return 0; 27 | } 28 | --------------------------------------------------------------------------------