dstu_core 0.1.0-x86_64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +90 -0
- data/Rakefile +16 -0
- data/lib/dstu_core/3.1/dstu_core_rb.so +0 -0
- data/lib/dstu_core/3.2/dstu_core_rb.so +0 -0
- data/lib/dstu_core/3.3/dstu_core_rb.so +0 -0
- data/lib/dstu_core/3.4/dstu_core_rb.so +0 -0
- data/lib/dstu_core/secretstream.rb +188 -0
- data/lib/dstu_core/version.rb +5 -0
- data/lib/dstu_core.rb +5 -0
- metadata +57 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: d2334ab3aa0124cebb58c7581ae4aeb17da063c86cc204c81c4520d2828e31f5
|
|
4
|
+
data.tar.gz: ed3fd69afa6c610c3ab0400b57df533d1884a1b7890b87f3cba4dbf3578a4d1f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8e1f3bd238c2610b0d49f299d5491da7edcb8c44ad64ec2a1dae830909e5c731e6be51133373179da81ca370e0adbfd7296e23cb0feb4548fe6c15fbcb58886e
|
|
7
|
+
data.tar.gz: 8239f6561bb4ab5882b40d75c415cbb45dc6c607d46bb9737fa32dbfc7121a219a6f30d5497d1b3f26eae767cdbd1901f7a77d9b3eb1b1cc48fbdc1d9fac62be
|
data/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# dstu-core (Ruby bindings)
|
|
2
|
+
|
|
3
|
+
**Provisional — not published to RubyGems, not independently audited.** See the root project's
|
|
4
|
+
`docs/SECURITY.md` and `docs/DECISIONS.md` for the full threat model and per-construction status.
|
|
5
|
+
This binding wraps the full `dstu_core::crypto_*` surface (`docs/bindings-strategy.md` T-160) —
|
|
6
|
+
install from source as shown below.
|
|
7
|
+
|
|
8
|
+
## Installing (from source)
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
gem install bundler
|
|
12
|
+
bundle install
|
|
13
|
+
bundle exec rake compile
|
|
14
|
+
ruby -Ilib -e 'require "dstu_core"; DstuCore.self_test'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`magnus`/`rb_sys` need a matching Ruby + C toolchain to build the native extension — a real
|
|
18
|
+
`gcc`/`clang` install, not just Ruby itself. On Windows specifically, install the **DevKit**
|
|
19
|
+
variant of Ruby (bundles a matching MSYS2/mingw-w64-ucrt toolchain — a plain Ruby install has no
|
|
20
|
+
compiler wired up at all):
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
winget install --id RubyInstallerTeam.RubyWithDevKit.3.3 --exact
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`rb-sys`'s `bindgen` step also needs a `libclang` that matches Ruby's own mingw-ucrt target — a
|
|
27
|
+
generic pre-existing Windows LLVM install parses Ruby's headers incorrectly. Install the matching
|
|
28
|
+
MSYS2 package and point `LIBCLANG_PATH` at it:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
pacman -S --needed mingw-w64-ucrt-x86_64-clang # via `ridk` or an MSYS2 shell
|
|
32
|
+
export LIBCLANG_PATH="/path/to/msys64/ucrt64/bin"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`bundle exec rake compile` builds the Rust extension and copies it into `lib/dstu_core/`.
|
|
36
|
+
`DstuCore.self_test` re-runs `dstu_core::selftest::run()` (`docs/TASKS.md` T-161) against the
|
|
37
|
+
exact compiled build and raises `DstuCore::Error` if anything official-vector-level is wrong — the
|
|
38
|
+
first thing to run after any build to confirm it actually works, not just compiled.
|
|
39
|
+
|
|
40
|
+
This crate is its own Cargo workspace, split across `Cargo.toml` (the workspace root) and
|
|
41
|
+
`ext/dstu_core_rb/Cargo.toml` (the actual crate) — separate from the repo root
|
|
42
|
+
(`docs/DECISIONS.md` D-119) — build/test it from inside this directory, not from the repo root.
|
|
43
|
+
A **source** install (the steps above) needs this repo's own `crates/dstu-core` alongside it, since
|
|
44
|
+
`ext/dstu_core_rb/Cargo.toml` depends on it by relative path — it cannot install standalone outside
|
|
45
|
+
this repo. `rake native gem` instead builds a precompiled, platform-tagged gem that ships the
|
|
46
|
+
compiled extension directly and installs anywhere (see `docs/DECISIONS.md` D-136).
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
Every method/class below lives directly on the `DstuCore` module (no further nesting). Every
|
|
51
|
+
`String` this binding touches is binary (`ASCII-8BIT`) — `.b`/`force_encoding("BINARY")` a UTF-8
|
|
52
|
+
string before comparing it against a decrypted result. See `examples/` for complete, runnable
|
|
53
|
+
scripts, and `spec/` for the full correctness/rejection/misuse suite each one is verified against
|
|
54
|
+
(D-64/D-65).
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
require "dstu_core"
|
|
58
|
+
|
|
59
|
+
key = DstuCore.secretbox_keygen
|
|
60
|
+
sealed = DstuCore.secretbox_seal(key, "a message worth protecting")
|
|
61
|
+
raise unless DstuCore.secretbox_open(key, sealed) == "a message worth protecting"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
| Module | Methods/classes | Notes |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `crypto_secretbox` | `secretbox_keygen`, `secretbox_seal`, `secretbox_open` | Single-message authenticated encryption. `examples/secretbox.rb`. |
|
|
67
|
+
| `crypto_box` | `box_keygen`, `box_public_key`, `box_seal`, `box_open` | Public-key encryption (hybrid via KDF over `hazmat::dstu9041`, `l(p)=256`, D-169). `box_seal`/`box_open` are not memory-bounded — the whole message is held in memory. `examples/box.rb`. |
|
|
68
|
+
| `crypto_box512` | `box512_keygen`, `box512_public_key`, `box512_seal`, `box512_open` | `l(p)=512`/E512/1 sibling of `crypto_box` (T-193/T-204). `examples/box512.rb`. |
|
|
69
|
+
| `crypto_secretstream` | `secretstream_keygen`, `SecretStreamPushState`, `SecretStreamPullState`, `SecretStreamWriter`, `SecretStreamReader` | Chunked streaming AEAD. `SecretStreamWriter`/`Reader` (modeled on stdlib's own `Zlib::GzipWriter`/`GzipReader`) wire format matches `uacrypt encrypt`/`decrypt` exactly (D-118). `examples/secretstream_file.rb`. |
|
|
70
|
+
| `crypto_sign` | `sign_keygen`, `sign_verifying_key`, `sign_message`, `sign_verify` | DSTU 4145 `m=163` digital signatures, deterministic nonce (no RNG dependency). `examples/sign.rb`. |
|
|
71
|
+
| `crypto_sign257` | `sign257_keygen`, `sign257_verifying_key`, `sign257_message`, `sign257_verify` | `m=257` sibling of `crypto_sign` (T-199/T-204) — the curve real Diia-issued qualified signatures use. `examples/sign257.rb`. |
|
|
72
|
+
| `crypto_pwhash` | `pwhash_hash_password`, `pwhash_verify_password`, `PWHASH_INTERACTIVE`/`PWHASH_MODERATE`/`PWHASH_SENSITIVE` | Argon2id (the one deliberately non-DSTU component, D-49/D-50). `examples/password_hashing.rb`. |
|
|
73
|
+
| `crypto_auth` | `auth_keygen`, `auth`, `auth_verify` | Keyed message authentication (Kupyna-KMAC). `examples/misc.rb`. |
|
|
74
|
+
| `crypto_kdf` | `kdf_keygen`, `kdf_derive_subkey` | Deterministic subkey derivation. `examples/misc.rb`. |
|
|
75
|
+
| `crypto_generichash` | `kupyna256`, `kupyna512`, `Kupyna256Hasher`, `Kupyna512Hasher` | One-shot and streaming Kupyna hashing. `examples/misc.rb`. |
|
|
76
|
+
| `crypto_stream` | `stream_keygen`, `stream_encrypt`, `stream_decrypt` | Strumok-256 keystream — **unauthenticated**, `stream_decrypt` never fails on tampered input. `examples/misc.rb`. |
|
|
77
|
+
| `randombytes` | `randombytes_buf` | CSPRNG-backed random bytes. `examples/misc.rb`. |
|
|
78
|
+
| — | `self_test`, `DstuCore::Error` | Runtime KAT self-check (T-161); the one exception class every crypto-operation failure raises (`ArgumentError` covers caller-input mistakes like a wrong-length key instead). |
|
|
79
|
+
|
|
80
|
+
## Testing
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
bundle exec rubocop
|
|
84
|
+
bundle exec rspec
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`cargo build -p uacrypt --release` (from the repo root) first if you want
|
|
88
|
+
`spec/secretstream_spec.rb`'s live `uacrypt` CLI interop test to actually run instead of being
|
|
89
|
+
`skip`ped. `cargo xtask ruby` (from the repo root) runs this whole sequence, including that build
|
|
90
|
+
step and `rake compile`, in one command.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rb_sys/extensiontask"
|
|
5
|
+
require "rspec/core/rake_task"
|
|
6
|
+
|
|
7
|
+
GEMSPEC = Gem::Specification.load("dstu_core.gemspec")
|
|
8
|
+
|
|
9
|
+
RbSys::ExtensionTask.new("dstu_core_rb", GEMSPEC) do |ext|
|
|
10
|
+
ext.lib_dir = "lib/dstu_core"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
14
|
+
|
|
15
|
+
task build: :compile
|
|
16
|
+
task default: %i[compile spec]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# `crypto_secretstream` idiomatic wrapper (docs/DECISIONS.md D-118, docs/bindings-strategy.md
|
|
4
|
+
# T-160 step 3) - hides chunk/tag/header bookkeeping behind `write`/`each`, built in pure Ruby on
|
|
5
|
+
# top of the low-level SecretStreamPushState/SecretStreamPullState the compiled extension already
|
|
6
|
+
# exposes (step 2), rather than new Rust glue. Modeled on stdlib's own
|
|
7
|
+
# Zlib::GzipWriter/Zlib::GzipReader - the same "wraps an IO, transforms chunks transparently"
|
|
8
|
+
# shape, the closest Ruby-native precedent for this problem (matching Python's file-like object,
|
|
9
|
+
# Node's stream.Transform).
|
|
10
|
+
#
|
|
11
|
+
# **Wire format matches `uacrypt encrypt`/`decrypt` exactly**
|
|
12
|
+
# (crates/uacrypt/src/lib.rs's `run_secretstream_encrypt`/`run_secretstream_decrypt`, D-68):
|
|
13
|
+
# `header (32 bytes)` followed by one record per chunk, `tag_byte (1) || chunk_len_u32_le (4) ||
|
|
14
|
+
# ciphertext (chunk_len) || auth_tag (16)`, chunks capped at 8 KiB (matching
|
|
15
|
+
# `SECRETSTREAM_CHUNK_BYTES`, not an independent choice) - a file `SecretStreamWriter` writes is
|
|
16
|
+
# decryptable by `uacrypt decrypt` and vice versa.
|
|
17
|
+
#
|
|
18
|
+
# **Every `String` this wrapper touches is binary (`ASCII-8BIT`/`BINARY`)**, both what it writes
|
|
19
|
+
# to `out`/`inp` and what `#read_all`/`#each` yield - matching every underlying `crypto_*` wrapper
|
|
20
|
+
# function (`RString::to_bytes`, D-134). A caller passing UTF-8 text must `.b`/
|
|
21
|
+
# `force_encoding("BINARY")` before comparing against the decrypted result, or the comparison sees
|
|
22
|
+
# differing encodings and fails even when the bytes match (`"привіт".b == "привіт"` is `false` in
|
|
23
|
+
# Ruby) - this is a caller-side encoding-compare gotcha, not a bug in this wrapper.
|
|
24
|
+
module DstuCore
|
|
25
|
+
# Matches crates/uacrypt/src/lib.rs's SECRETSTREAM_CHUNK_BYTES exactly - required for
|
|
26
|
+
# wire-format interop with `uacrypt encrypt`/`decrypt`, not an independent choice.
|
|
27
|
+
SECRETSTREAM_CHUNK_BYTES = 8 * 1024
|
|
28
|
+
SECRETSTREAM_AUTH_TAG_BYTES = 16
|
|
29
|
+
|
|
30
|
+
# Write-only wrapper: buffers input and pushes each full 8 KiB chunk to `out` as it fills, hiding
|
|
31
|
+
# the header/tag/framing bookkeeping entirely.
|
|
32
|
+
#
|
|
33
|
+
# File.open("out.bin", "wb") do |f|
|
|
34
|
+
# DstuCore::SecretStreamWriter.open(key, f) { |w| w.write("a whole file, incrementally") }
|
|
35
|
+
# end
|
|
36
|
+
class SecretStreamWriter
|
|
37
|
+
def initialize(key, out)
|
|
38
|
+
@out = out
|
|
39
|
+
@out.binmode if @out.respond_to?(:binmode)
|
|
40
|
+
@push = SecretStreamPushState.new(key)
|
|
41
|
+
@out.write(@push.header)
|
|
42
|
+
@buf = +""
|
|
43
|
+
@closed = false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Block form: yields a writer, then closes it - **only on the success path**. The D-118
|
|
47
|
+
# pitfall this deliberately avoids: Ruby's own "always runs, even on error" cleanup idiom
|
|
48
|
+
# (`ensure`, the shape `File.open`/`Zlib::GzipWriter.wrap` both use) would finalize (emit the
|
|
49
|
+
# `Final` chunk) even when the block raised partway through, producing a stream that looks
|
|
50
|
+
# complete but silently drops data - violates D-65's "no partial output treated as valid on
|
|
51
|
+
# failure." If a truncated-but-decryptable prefix is genuinely wanted, call `close` explicitly
|
|
52
|
+
# inside a `rescue` clause instead.
|
|
53
|
+
def self.open(key, out)
|
|
54
|
+
writer = new(key, out)
|
|
55
|
+
yield writer
|
|
56
|
+
writer.close
|
|
57
|
+
writer
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def closed?
|
|
61
|
+
@closed
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Buffers `data`, pushing any now-complete 8 KiB chunks immediately. The trailing partial (or
|
|
65
|
+
# exactly-8-KiB) chunk is always held back until `close`, since only `close` knows no more
|
|
66
|
+
# data is coming - the same one-chunk-ahead reasoning `uacrypt encrypt` itself uses to tag the
|
|
67
|
+
# true last chunk `Final`, not an extra empty one after it.
|
|
68
|
+
def write(data)
|
|
69
|
+
raise IOError, "closed stream" if @closed
|
|
70
|
+
|
|
71
|
+
@buf << data.b
|
|
72
|
+
while @buf.bytesize > SECRETSTREAM_CHUNK_BYTES
|
|
73
|
+
push_chunk(SECRETSTREAM_TAG_MESSAGE, @buf.byteslice(0, SECRETSTREAM_CHUNK_BYTES))
|
|
74
|
+
@buf = @buf.byteslice(SECRETSTREAM_CHUNK_BYTES..) || +""
|
|
75
|
+
end
|
|
76
|
+
data.bytesize
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
alias << write
|
|
80
|
+
|
|
81
|
+
# Flushes any buffered bytes as the stream's Final chunk. Idempotent - safe to call more than
|
|
82
|
+
# once, matching normal Ruby `IO#close` semantics.
|
|
83
|
+
def close
|
|
84
|
+
return if @closed
|
|
85
|
+
|
|
86
|
+
push_chunk(SECRETSTREAM_TAG_FINAL, @buf)
|
|
87
|
+
@buf = +""
|
|
88
|
+
@closed = true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
def push_chunk(tag, data)
|
|
94
|
+
ciphertext, auth_tag = @push.push(tag, data)
|
|
95
|
+
@out.write([tag].pack("C"))
|
|
96
|
+
@out.write([data.bytesize].pack("V"))
|
|
97
|
+
@out.write(ciphertext)
|
|
98
|
+
@out.write(auth_tag)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Read-only, chunk-iterating wrapper: reads and decrypts one chunk from `inp` at a time.
|
|
103
|
+
# `include Enumerable` gives `to_a`/`map`/etc. for free; `read_all` joins every plaintext chunk
|
|
104
|
+
# into one `String`, bounded only by available memory (the same caveat `crypto_secretbox`
|
|
105
|
+
# already carries). Raises `DstuCore::Error` on authentication failure or truncation - a
|
|
106
|
+
# dropped/tampered/reordered chunk, or a stream that ends before a Final chunk, both fail closed
|
|
107
|
+
# rather than yielding wrong plaintext.
|
|
108
|
+
#
|
|
109
|
+
# File.open("out.bin", "rb") do |f|
|
|
110
|
+
# plaintext = DstuCore::SecretStreamReader.open(key, f, &:read_all)
|
|
111
|
+
# end
|
|
112
|
+
class SecretStreamReader
|
|
113
|
+
include Enumerable
|
|
114
|
+
|
|
115
|
+
def initialize(key, inp)
|
|
116
|
+
@inp = inp
|
|
117
|
+
@inp.binmode if @inp.respond_to?(:binmode)
|
|
118
|
+
header = read_exact(32, "header")
|
|
119
|
+
@pull = SecretStreamPullState.new(key, header)
|
|
120
|
+
@done = false
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def self.open(key, inp)
|
|
124
|
+
reader = new(key, inp)
|
|
125
|
+
yield reader
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def each
|
|
129
|
+
return enum_for(:each) unless block_given?
|
|
130
|
+
|
|
131
|
+
yield next_chunk until @done
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def read_all
|
|
135
|
+
each.to_a.join
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# No-op - present for symmetry with SecretStreamWriter and Ruby's own IO-like `close` idiom.
|
|
139
|
+
def close; end
|
|
140
|
+
|
|
141
|
+
private
|
|
142
|
+
|
|
143
|
+
def next_chunk
|
|
144
|
+
tag_byte = read_exact(1, "chunk tag").unpack1("C")
|
|
145
|
+
chunk_len = read_exact(4, "chunk length").unpack1("V")
|
|
146
|
+
# `chunk_len` is untrusted wire input, read before any tag verification - reject an
|
|
147
|
+
# oversized declared length before acting on it (`read_exact` would otherwise try to
|
|
148
|
+
# accumulate up to `chunk_len` bytes from `inp`, which for a socket/pipe could mean
|
|
149
|
+
# gigabytes before ever failing). Matches `uacrypt decrypt`'s own
|
|
150
|
+
# `CliError::SecretstreamChunkTooLarge` bound (`crates/uacrypt/src/lib.rs`).
|
|
151
|
+
if chunk_len > SECRETSTREAM_CHUNK_BYTES
|
|
152
|
+
raise DstuCore::Error,
|
|
153
|
+
"secretstream chunk too large: declared #{chunk_len} bytes, max #{SECRETSTREAM_CHUNK_BYTES}"
|
|
154
|
+
end
|
|
155
|
+
ciphertext = read_exact(chunk_len, "chunk ciphertext")
|
|
156
|
+
auth_tag = read_exact(SECRETSTREAM_AUTH_TAG_BYTES, "chunk auth tag")
|
|
157
|
+
tag, plaintext = @pull.pull(tag_byte, ciphertext, auth_tag)
|
|
158
|
+
if tag == SECRETSTREAM_TAG_FINAL
|
|
159
|
+
# Matches `uacrypt decrypt`'s own `CliError::SecretstreamTrailingData` check - reject
|
|
160
|
+
# bytes remaining after `Final` rather than silently ignoring them. Checked before
|
|
161
|
+
# `plaintext` is returned, so a trailing-data stream never yields this last chunk either
|
|
162
|
+
# via `each` or `read_all`.
|
|
163
|
+
raise DstuCore::Error, "trailing data after the secretstream's Final chunk" if @inp.read(1)
|
|
164
|
+
|
|
165
|
+
@done = true
|
|
166
|
+
end
|
|
167
|
+
plaintext
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def read_exact(size, what)
|
|
171
|
+
pieces = []
|
|
172
|
+
remaining = size
|
|
173
|
+
while remaining.positive?
|
|
174
|
+
piece = @inp.read(remaining)
|
|
175
|
+
break unless piece
|
|
176
|
+
|
|
177
|
+
pieces << piece
|
|
178
|
+
remaining -= piece.bytesize
|
|
179
|
+
end
|
|
180
|
+
data = pieces.join
|
|
181
|
+
if data.bytesize != size
|
|
182
|
+
raise DstuCore::Error, "truncated secretstream: expected #{size} bytes for #{what}, got #{data.bytesize}"
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
data
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
data/lib/dstu_core.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dstu_core
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: x86_64-linux
|
|
6
|
+
authors:
|
|
7
|
+
- dstu-core contributors
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-08-13 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Ruby bindings for dstu-core (Ukrainian DSTU cryptographic standards)
|
|
14
|
+
- provisional, not yet published to RubyGems.
|
|
15
|
+
email:
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- README.md
|
|
21
|
+
- Rakefile
|
|
22
|
+
- lib/dstu_core.rb
|
|
23
|
+
- lib/dstu_core/3.1/dstu_core_rb.so
|
|
24
|
+
- lib/dstu_core/3.2/dstu_core_rb.so
|
|
25
|
+
- lib/dstu_core/3.3/dstu_core_rb.so
|
|
26
|
+
- lib/dstu_core/3.4/dstu_core_rb.so
|
|
27
|
+
- lib/dstu_core/secretstream.rb
|
|
28
|
+
- lib/dstu_core/version.rb
|
|
29
|
+
homepage: https://github.com/user137/uacrypt
|
|
30
|
+
licenses:
|
|
31
|
+
- MIT
|
|
32
|
+
- Apache-2.0
|
|
33
|
+
metadata:
|
|
34
|
+
rubygems_mfa_required: 'true'
|
|
35
|
+
post_install_message:
|
|
36
|
+
rdoc_options: []
|
|
37
|
+
require_paths:
|
|
38
|
+
- lib
|
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '3.1'
|
|
44
|
+
- - "<"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 3.5.dev
|
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
|
+
requirements:
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '0'
|
|
52
|
+
requirements: []
|
|
53
|
+
rubygems_version: 3.5.23
|
|
54
|
+
signing_key:
|
|
55
|
+
specification_version: 4
|
|
56
|
+
summary: Ruby bindings for dstu-core (Ukrainian DSTU cryptographic standards)
|
|
57
|
+
test_files: []
|