diff --git a/appveyor/qopenglversionfunctions.h b/appveyor/qopenglversionfunctions.h index aa32e153f..6a4e4483e 100644 --- a/appveyor/qopenglversionfunctions.h +++ b/appveyor/qopenglversionfunctions.h @@ -61,67 +61,49 @@ class QOpenGLContext; #pragma qt_sync_stop_processing #endif -struct QOpenGLVersionStatus -{ - enum OpenGLStatus { - CoreStatus, - DeprecatedStatus, - InvalidStatus - }; +struct QOpenGLVersionStatus { + enum OpenGLStatus { CoreStatus, DeprecatedStatus, InvalidStatus }; - Q_DECL_CONSTEXPR QOpenGLVersionStatus() - : version(0, 0), - status(InvalidStatus) - {} + Q_DECL_CONSTEXPR QOpenGLVersionStatus() : version(0, 0), status(InvalidStatus) {} - Q_DECL_CONSTEXPR QOpenGLVersionStatus(int majorVersion, int minorVersion, QOpenGLVersionStatus::OpenGLStatus functionStatus) - : version(majorVersion, minorVersion), - status(functionStatus) - {} + Q_DECL_CONSTEXPR QOpenGLVersionStatus(int majorVersion, int minorVersion, + QOpenGLVersionStatus::OpenGLStatus functionStatus) + : version(majorVersion, minorVersion), status(functionStatus) {} QPair version; OpenGLStatus status; }; -inline uint qHash(const QOpenGLVersionStatus &v, uint seed = 0) Q_DECL_NOTHROW -{ - return qHash(static_cast(v.status * 1000) - + v.version.first * 100 + v.version.second * 10, seed); +inline uint qHash(const QOpenGLVersionStatus &v, uint seed = 0) Q_DECL_NOTHROW { + return qHash(static_cast(v.status * 1000) + v.version.first * 100 + v.version.second * 10, + seed); } -Q_DECL_CONSTEXPR inline bool operator==(const QOpenGLVersionStatus &lhs, const QOpenGLVersionStatus &rhs) -{ +Q_DECL_CONSTEXPR inline bool operator==(const QOpenGLVersionStatus &lhs, + const QOpenGLVersionStatus &rhs) { return lhs.status == rhs.status && lhs.version == rhs.version; } -Q_DECL_CONSTEXPR inline bool operator!=(const QOpenGLVersionStatus &lhs, const QOpenGLVersionStatus &rhs) -{ +Q_DECL_CONSTEXPR inline bool operator!=(const QOpenGLVersionStatus &lhs, + const QOpenGLVersionStatus &rhs) { return !operator==(lhs, rhs); } -class QOpenGLVersionFunctionsBackend -{ -public: - QOpenGLVersionFunctionsBackend(QOpenGLContext *ctx) - : context(ctx) - {} +class QOpenGLVersionFunctionsBackend { + public: + QOpenGLVersionFunctionsBackend(QOpenGLContext *ctx) : context(ctx) {} QOpenGLContext *context; QAtomicInt refs; }; -class QAbstractOpenGLFunctionsPrivate -{ -public: - QAbstractOpenGLFunctionsPrivate() - : owningContext(0), - initialized(false) - {} +class QAbstractOpenGLFunctionsPrivate { + public: + QAbstractOpenGLFunctionsPrivate() : owningContext(0), initialized(false) {} static QOpenGLVersionFunctionsBackend *functionsBackend(QOpenGLContext *context, const QOpenGLVersionStatus &v); - static void insertFunctionsBackend(QOpenGLContext *context, - const QOpenGLVersionStatus &v, + static void insertFunctionsBackend(QOpenGLContext *context, const QOpenGLVersionStatus &v, QOpenGLVersionFunctionsBackend *backend); static void removeFunctionsBackend(QOpenGLContext *context, const QOpenGLVersionStatus &v); @@ -129,16 +111,15 @@ public: bool initialized; }; -class QAbstractOpenGLFunctions -{ -public: +class QAbstractOpenGLFunctions { + public: virtual ~QAbstractOpenGLFunctions(); virtual bool initializeOpenGLFunctions(); Q_DECLARE_PRIVATE(QAbstractOpenGLFunctions) -protected: + protected: QAbstractOpenGLFunctions(); QAbstractOpenGLFunctionsPrivate *d_ptr; @@ -152,1204 +133,1489 @@ protected: #if !defined(QT_OPENGL_ES_2) -class QOpenGLFunctions_1_0_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_0_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_0_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.0 core functions - void (QOPENGLF_APIENTRYP Viewport)(GLint x, GLint y, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP DepthRange)(GLdouble nearVal, GLdouble farVal); - GLboolean (QOPENGLF_APIENTRYP IsEnabled)(GLenum cap); - void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetTexParameteriv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); - const GLubyte * (QOPENGLF_APIENTRYP GetString)(GLenum name); - void (QOPENGLF_APIENTRYP GetIntegerv)(GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetFloatv)(GLenum pname, GLfloat *params); - GLenum (QOPENGLF_APIENTRYP GetError)(); - void (QOPENGLF_APIENTRYP GetDoublev)(GLenum pname, GLdouble *params); - void (QOPENGLF_APIENTRYP GetBooleanv)(GLenum pname, GLboolean *params); - void (QOPENGLF_APIENTRYP ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); - void (QOPENGLF_APIENTRYP ReadBuffer)(GLenum mode); - void (QOPENGLF_APIENTRYP PixelStorei)(GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP PixelStoref)(GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP DepthFunc)(GLenum func); - void (QOPENGLF_APIENTRYP StencilOp)(GLenum fail, GLenum zfail, GLenum zpass); - void (QOPENGLF_APIENTRYP StencilFunc)(GLenum func, GLint ref, GLuint mask); - void (QOPENGLF_APIENTRYP LogicOp)(GLenum opcode); - void (QOPENGLF_APIENTRYP BlendFunc)(GLenum sfactor, GLenum dfactor); - void (QOPENGLF_APIENTRYP Flush)(); - void (QOPENGLF_APIENTRYP Finish)(); - void (QOPENGLF_APIENTRYP Enable)(GLenum cap); - void (QOPENGLF_APIENTRYP Disable)(GLenum cap); - void (QOPENGLF_APIENTRYP DepthMask)(GLboolean flag); - void (QOPENGLF_APIENTRYP ColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); - void (QOPENGLF_APIENTRYP StencilMask)(GLuint mask); - void (QOPENGLF_APIENTRYP ClearDepth)(GLdouble depth); - void (QOPENGLF_APIENTRYP ClearStencil)(GLint s); - void (QOPENGLF_APIENTRYP ClearColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - void (QOPENGLF_APIENTRYP Clear)(GLbitfield mask); - void (QOPENGLF_APIENTRYP DrawBuffer)(GLenum mode); - void (QOPENGLF_APIENTRYP TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP TexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP TexParameteriv)(GLenum target, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP TexParameteri)(GLenum target, GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP TexParameterf)(GLenum target, GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP Scissor)(GLint x, GLint y, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP PolygonMode)(GLenum face, GLenum mode); - void (QOPENGLF_APIENTRYP PointSize)(GLfloat size); - void (QOPENGLF_APIENTRYP LineWidth)(GLfloat width); - void (QOPENGLF_APIENTRYP Hint)(GLenum target, GLenum mode); - void (QOPENGLF_APIENTRYP FrontFace)(GLenum mode); - void (QOPENGLF_APIENTRYP CullFace)(GLenum mode); - + void(QOPENGLF_APIENTRYP Viewport)(GLint x, GLint y, GLsizei width, GLsizei height); + void(QOPENGLF_APIENTRYP DepthRange)(GLdouble nearVal, GLdouble farVal); + GLboolean(QOPENGLF_APIENTRYP IsEnabled)(GLenum cap); + void(QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, + GLint *params); + void(QOPENGLF_APIENTRYP GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, + GLfloat *params); + void(QOPENGLF_APIENTRYP GetTexParameteriv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, + GLvoid *pixels); + const GLubyte *(QOPENGLF_APIENTRYP GetString)(GLenum name); + void(QOPENGLF_APIENTRYP GetIntegerv)(GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetFloatv)(GLenum pname, GLfloat *params); + GLenum(QOPENGLF_APIENTRYP GetError)(); + void(QOPENGLF_APIENTRYP GetDoublev)(GLenum pname, GLdouble *params); + void(QOPENGLF_APIENTRYP GetBooleanv)(GLenum pname, GLboolean *params); + void(QOPENGLF_APIENTRYP ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels); + void(QOPENGLF_APIENTRYP ReadBuffer)(GLenum mode); + void(QOPENGLF_APIENTRYP PixelStorei)(GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP PixelStoref)(GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP DepthFunc)(GLenum func); + void(QOPENGLF_APIENTRYP StencilOp)(GLenum fail, GLenum zfail, GLenum zpass); + void(QOPENGLF_APIENTRYP StencilFunc)(GLenum func, GLint ref, GLuint mask); + void(QOPENGLF_APIENTRYP LogicOp)(GLenum opcode); + void(QOPENGLF_APIENTRYP BlendFunc)(GLenum sfactor, GLenum dfactor); + void(QOPENGLF_APIENTRYP Flush)(); + void(QOPENGLF_APIENTRYP Finish)(); + void(QOPENGLF_APIENTRYP Enable)(GLenum cap); + void(QOPENGLF_APIENTRYP Disable)(GLenum cap); + void(QOPENGLF_APIENTRYP DepthMask)(GLboolean flag); + void(QOPENGLF_APIENTRYP ColorMask)(GLboolean red, GLboolean green, GLboolean blue, + GLboolean alpha); + void(QOPENGLF_APIENTRYP StencilMask)(GLuint mask); + void(QOPENGLF_APIENTRYP ClearDepth)(GLdouble depth); + void(QOPENGLF_APIENTRYP ClearStencil)(GLint s); + void(QOPENGLF_APIENTRYP ClearColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void(QOPENGLF_APIENTRYP Clear)(GLbitfield mask); + void(QOPENGLF_APIENTRYP DrawBuffer)(GLenum mode); + void(QOPENGLF_APIENTRYP TexImage2D)(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, + GLenum type, const GLvoid *pixels); + void(QOPENGLF_APIENTRYP TexImage1D)(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLint border, GLenum format, GLenum type, + const GLvoid *pixels); + void(QOPENGLF_APIENTRYP TexParameteriv)(GLenum target, GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP TexParameteri)(GLenum target, GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params); + void(QOPENGLF_APIENTRYP TexParameterf)(GLenum target, GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP Scissor)(GLint x, GLint y, GLsizei width, GLsizei height); + void(QOPENGLF_APIENTRYP PolygonMode)(GLenum face, GLenum mode); + void(QOPENGLF_APIENTRYP PointSize)(GLfloat size); + void(QOPENGLF_APIENTRYP LineWidth)(GLfloat width); + void(QOPENGLF_APIENTRYP Hint)(GLenum target, GLenum mode); + void(QOPENGLF_APIENTRYP FrontFace)(GLenum mode); + void(QOPENGLF_APIENTRYP CullFace)(GLenum mode); }; -class QOpenGLFunctions_1_1_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_1_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_1_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.1 core functions - void (QOPENGLF_APIENTRYP Indexubv)(const GLubyte *c); - void (QOPENGLF_APIENTRYP Indexub)(GLubyte c); - GLboolean (QOPENGLF_APIENTRYP IsTexture)(GLuint texture); - void (QOPENGLF_APIENTRYP GenTextures)(GLsizei n, GLuint *textures); - void (QOPENGLF_APIENTRYP DeleteTextures)(GLsizei n, const GLuint *textures); - void (QOPENGLF_APIENTRYP BindTexture)(GLenum target, GLuint texture); - void (QOPENGLF_APIENTRYP TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP TexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP CopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP CopyTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); - void (QOPENGLF_APIENTRYP CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); - void (QOPENGLF_APIENTRYP CopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); - void (QOPENGLF_APIENTRYP PolygonOffset)(GLfloat factor, GLfloat units); - void (QOPENGLF_APIENTRYP GetPointerv)(GLenum pname, GLvoid* *params); - void (QOPENGLF_APIENTRYP DrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); - void (QOPENGLF_APIENTRYP DrawArrays)(GLenum mode, GLint first, GLsizei count); - + void(QOPENGLF_APIENTRYP Indexubv)(const GLubyte *c); + void(QOPENGLF_APIENTRYP Indexub)(GLubyte c); + GLboolean(QOPENGLF_APIENTRYP IsTexture)(GLuint texture); + void(QOPENGLF_APIENTRYP GenTextures)(GLsizei n, GLuint *textures); + void(QOPENGLF_APIENTRYP DeleteTextures)(GLsizei n, const GLuint *textures); + void(QOPENGLF_APIENTRYP BindTexture)(GLenum target, GLuint texture); + void(QOPENGLF_APIENTRYP TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *pixels); + void(QOPENGLF_APIENTRYP TexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, + GLenum format, GLenum type, const GLvoid *pixels); + void(QOPENGLF_APIENTRYP CopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, GLsizei width, + GLsizei height); + void(QOPENGLF_APIENTRYP CopyTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLint x, + GLint y, GLsizei width); + void(QOPENGLF_APIENTRYP CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + void(QOPENGLF_APIENTRYP CopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border); + void(QOPENGLF_APIENTRYP PolygonOffset)(GLfloat factor, GLfloat units); + void(QOPENGLF_APIENTRYP GetPointerv)(GLenum pname, GLvoid **params); + void(QOPENGLF_APIENTRYP DrawElements)(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); + void(QOPENGLF_APIENTRYP DrawArrays)(GLenum mode, GLint first, GLsizei count); }; -class QOpenGLFunctions_1_2_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_2_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_2_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.2 core functions - void (QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); - void (QOPENGLF_APIENTRYP BlendEquation)(GLenum mode); - void (QOPENGLF_APIENTRYP BlendColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - + void(QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height); + void(QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum format, GLenum type, + const GLvoid *pixels); + void(QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels); + void(QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, + GLenum type, const GLvoid *indices); + void(QOPENGLF_APIENTRYP BlendEquation)(GLenum mode); + void(QOPENGLF_APIENTRYP BlendColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); }; -class QOpenGLFunctions_1_3_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_3_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_3_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.3 core functions - void (QOPENGLF_APIENTRYP GetCompressedTexImage)(GLenum target, GLint level, GLvoid *img); - void (QOPENGLF_APIENTRYP CompressedTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP SampleCoverage)(GLfloat value, GLboolean invert); - void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture); - + void(QOPENGLF_APIENTRYP GetCompressedTexImage)(GLenum target, GLint level, GLvoid *img); + void(QOPENGLF_APIENTRYP CompressedTexSubImage1D)(GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data); + void(QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data); + void(QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data); + void(QOPENGLF_APIENTRYP CompressedTexImage1D)(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLint border, GLsizei imageSize, + const GLvoid *data); + void(QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data); + void(QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLsizei imageSize, + const GLvoid *data); + void(QOPENGLF_APIENTRYP SampleCoverage)(GLfloat value, GLboolean invert); + void(QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture); }; -class QOpenGLFunctions_1_4_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_4_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_4_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.4 core functions - void (QOPENGLF_APIENTRYP PointParameteriv)(GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP PointParameteri)(GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP PointParameterfv)(GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP PointParameterf)(GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP MultiDrawElements)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount); - void (QOPENGLF_APIENTRYP MultiDrawArrays)(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); - void (QOPENGLF_APIENTRYP BlendFuncSeparate)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); - + void(QOPENGLF_APIENTRYP PointParameteriv)(GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP PointParameteri)(GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP PointParameterfv)(GLenum pname, const GLfloat *params); + void(QOPENGLF_APIENTRYP PointParameterf)(GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP MultiDrawElements)(GLenum mode, const GLsizei *count, GLenum type, + const GLvoid *const *indices, GLsizei drawcount); + void(QOPENGLF_APIENTRYP MultiDrawArrays)(GLenum mode, const GLint *first, const GLsizei *count, + GLsizei drawcount); + void(QOPENGLF_APIENTRYP BlendFuncSeparate)(GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorAlpha, GLenum dfactorAlpha); }; -class QOpenGLFunctions_1_5_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_5_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_5_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.5 core functions - void (QOPENGLF_APIENTRYP GetBufferPointerv)(GLenum target, GLenum pname, GLvoid* *params); - void (QOPENGLF_APIENTRYP GetBufferParameteriv)(GLenum target, GLenum pname, GLint *params); - GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); - GLvoid* (QOPENGLF_APIENTRYP MapBuffer)(GLenum target, GLenum access); - void (QOPENGLF_APIENTRYP GetBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); - void (QOPENGLF_APIENTRYP BufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); - void (QOPENGLF_APIENTRYP BufferData)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); - GLboolean (QOPENGLF_APIENTRYP IsBuffer)(GLuint buffer); - void (QOPENGLF_APIENTRYP GenBuffers)(GLsizei n, GLuint *buffers); - void (QOPENGLF_APIENTRYP DeleteBuffers)(GLsizei n, const GLuint *buffers); - void (QOPENGLF_APIENTRYP BindBuffer)(GLenum target, GLuint buffer); - void (QOPENGLF_APIENTRYP GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params); - void (QOPENGLF_APIENTRYP GetQueryObjectiv)(GLuint id, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetQueryiv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP EndQuery)(GLenum target); - void (QOPENGLF_APIENTRYP BeginQuery)(GLenum target, GLuint id); - GLboolean (QOPENGLF_APIENTRYP IsQuery)(GLuint id); - void (QOPENGLF_APIENTRYP DeleteQueries)(GLsizei n, const GLuint *ids); - void (QOPENGLF_APIENTRYP GenQueries)(GLsizei n, GLuint *ids); - + void(QOPENGLF_APIENTRYP GetBufferPointerv)(GLenum target, GLenum pname, GLvoid **params); + void(QOPENGLF_APIENTRYP GetBufferParameteriv)(GLenum target, GLenum pname, GLint *params); + GLboolean(QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); + GLvoid *(QOPENGLF_APIENTRYP MapBuffer)(GLenum target, GLenum access); + void(QOPENGLF_APIENTRYP GetBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, + GLvoid *data); + void(QOPENGLF_APIENTRYP BufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, + const GLvoid *data); + void(QOPENGLF_APIENTRYP BufferData)(GLenum target, GLsizeiptr size, const GLvoid *data, + GLenum usage); + GLboolean(QOPENGLF_APIENTRYP IsBuffer)(GLuint buffer); + void(QOPENGLF_APIENTRYP GenBuffers)(GLsizei n, GLuint *buffers); + void(QOPENGLF_APIENTRYP DeleteBuffers)(GLsizei n, const GLuint *buffers); + void(QOPENGLF_APIENTRYP BindBuffer)(GLenum target, GLuint buffer); + void(QOPENGLF_APIENTRYP GetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params); + void(QOPENGLF_APIENTRYP GetQueryObjectiv)(GLuint id, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetQueryiv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP EndQuery)(GLenum target); + void(QOPENGLF_APIENTRYP BeginQuery)(GLenum target, GLuint id); + GLboolean(QOPENGLF_APIENTRYP IsQuery)(GLuint id); + void(QOPENGLF_APIENTRYP DeleteQueries)(GLsizei n, const GLuint *ids); + void(QOPENGLF_APIENTRYP GenQueries)(GLsizei n, GLuint *ids); }; -class QOpenGLFunctions_2_0_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_2_0_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_2_0_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 2.0 core functions - void (QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP ValidateProgram)(GLuint program); - void (QOPENGLF_APIENTRYP UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP UniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP UniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP Uniform4iv)(GLint location, GLsizei count, const GLint *value); - void (QOPENGLF_APIENTRYP Uniform3iv)(GLint location, GLsizei count, const GLint *value); - void (QOPENGLF_APIENTRYP Uniform2iv)(GLint location, GLsizei count, const GLint *value); - void (QOPENGLF_APIENTRYP Uniform1iv)(GLint location, GLsizei count, const GLint *value); - void (QOPENGLF_APIENTRYP Uniform4fv)(GLint location, GLsizei count, const GLfloat *value); - void (QOPENGLF_APIENTRYP Uniform3fv)(GLint location, GLsizei count, const GLfloat *value); - void (QOPENGLF_APIENTRYP Uniform2fv)(GLint location, GLsizei count, const GLfloat *value); - void (QOPENGLF_APIENTRYP Uniform1fv)(GLint location, GLsizei count, const GLfloat *value); - void (QOPENGLF_APIENTRYP Uniform4i)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); - void (QOPENGLF_APIENTRYP Uniform3i)(GLint location, GLint v0, GLint v1, GLint v2); - void (QOPENGLF_APIENTRYP Uniform2i)(GLint location, GLint v0, GLint v1); - void (QOPENGLF_APIENTRYP Uniform1i)(GLint location, GLint v0); - void (QOPENGLF_APIENTRYP Uniform4f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); - void (QOPENGLF_APIENTRYP Uniform3f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); - void (QOPENGLF_APIENTRYP Uniform2f)(GLint location, GLfloat v0, GLfloat v1); - void (QOPENGLF_APIENTRYP Uniform1f)(GLint location, GLfloat v0); - void (QOPENGLF_APIENTRYP UseProgram)(GLuint program); - void (QOPENGLF_APIENTRYP ShaderSource)(GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length); - void (QOPENGLF_APIENTRYP LinkProgram)(GLuint program); - GLboolean (QOPENGLF_APIENTRYP IsShader)(GLuint shader); - GLboolean (QOPENGLF_APIENTRYP IsProgram)(GLuint program); - void (QOPENGLF_APIENTRYP GetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid* *pointer); - void (QOPENGLF_APIENTRYP GetVertexAttribiv)(GLuint index, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetVertexAttribfv)(GLuint index, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetVertexAttribdv)(GLuint index, GLenum pname, GLdouble *params); - void (QOPENGLF_APIENTRYP GetUniformiv)(GLuint program, GLint location, GLint *params); - void (QOPENGLF_APIENTRYP GetUniformfv)(GLuint program, GLint location, GLfloat *params); - GLint (QOPENGLF_APIENTRYP GetUniformLocation)(GLuint program, const GLchar *name); - void (QOPENGLF_APIENTRYP GetShaderSource)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); - void (QOPENGLF_APIENTRYP GetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - void (QOPENGLF_APIENTRYP GetShaderiv)(GLuint shader, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetProgramInfoLog)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - void (QOPENGLF_APIENTRYP GetProgramiv)(GLuint program, GLenum pname, GLint *params); - GLint (QOPENGLF_APIENTRYP GetAttribLocation)(GLuint program, const GLchar *name); - void (QOPENGLF_APIENTRYP GetAttachedShaders)(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); - void (QOPENGLF_APIENTRYP GetActiveUniform)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); - void (QOPENGLF_APIENTRYP GetActiveAttrib)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); - void (QOPENGLF_APIENTRYP EnableVertexAttribArray)(GLuint index); - void (QOPENGLF_APIENTRYP DisableVertexAttribArray)(GLuint index); - void (QOPENGLF_APIENTRYP DetachShader)(GLuint program, GLuint shader); - void (QOPENGLF_APIENTRYP DeleteShader)(GLuint shader); - void (QOPENGLF_APIENTRYP DeleteProgram)(GLuint program); - GLuint (QOPENGLF_APIENTRYP CreateShader)(GLenum type); - GLuint (QOPENGLF_APIENTRYP CreateProgram)(); - void (QOPENGLF_APIENTRYP CompileShader)(GLuint shader); - void (QOPENGLF_APIENTRYP BindAttribLocation)(GLuint program, GLuint index, const GLchar *name); - void (QOPENGLF_APIENTRYP AttachShader)(GLuint program, GLuint shader); - void (QOPENGLF_APIENTRYP StencilMaskSeparate)(GLenum face, GLuint mask); - void (QOPENGLF_APIENTRYP StencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask); - void (QOPENGLF_APIENTRYP StencilOpSeparate)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); - void (QOPENGLF_APIENTRYP DrawBuffers)(GLsizei n, const GLenum *bufs); - void (QOPENGLF_APIENTRYP BlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha); - + void(QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint index, GLint size, GLenum type, + GLboolean normalized, GLsizei stride, + const GLvoid *pointer); + void(QOPENGLF_APIENTRYP ValidateProgram)(GLuint program); + void(QOPENGLF_APIENTRYP UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP UniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP UniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP Uniform4iv)(GLint location, GLsizei count, const GLint *value); + void(QOPENGLF_APIENTRYP Uniform3iv)(GLint location, GLsizei count, const GLint *value); + void(QOPENGLF_APIENTRYP Uniform2iv)(GLint location, GLsizei count, const GLint *value); + void(QOPENGLF_APIENTRYP Uniform1iv)(GLint location, GLsizei count, const GLint *value); + void(QOPENGLF_APIENTRYP Uniform4fv)(GLint location, GLsizei count, const GLfloat *value); + void(QOPENGLF_APIENTRYP Uniform3fv)(GLint location, GLsizei count, const GLfloat *value); + void(QOPENGLF_APIENTRYP Uniform2fv)(GLint location, GLsizei count, const GLfloat *value); + void(QOPENGLF_APIENTRYP Uniform1fv)(GLint location, GLsizei count, const GLfloat *value); + void(QOPENGLF_APIENTRYP Uniform4i)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void(QOPENGLF_APIENTRYP Uniform3i)(GLint location, GLint v0, GLint v1, GLint v2); + void(QOPENGLF_APIENTRYP Uniform2i)(GLint location, GLint v0, GLint v1); + void(QOPENGLF_APIENTRYP Uniform1i)(GLint location, GLint v0); + void(QOPENGLF_APIENTRYP Uniform4f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, + GLfloat v3); + void(QOPENGLF_APIENTRYP Uniform3f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void(QOPENGLF_APIENTRYP Uniform2f)(GLint location, GLfloat v0, GLfloat v1); + void(QOPENGLF_APIENTRYP Uniform1f)(GLint location, GLfloat v0); + void(QOPENGLF_APIENTRYP UseProgram)(GLuint program); + void(QOPENGLF_APIENTRYP ShaderSource)(GLuint shader, GLsizei count, const GLchar *const *string, + const GLint *length); + void(QOPENGLF_APIENTRYP LinkProgram)(GLuint program); + GLboolean(QOPENGLF_APIENTRYP IsShader)(GLuint shader); + GLboolean(QOPENGLF_APIENTRYP IsProgram)(GLuint program); + void(QOPENGLF_APIENTRYP GetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid **pointer); + void(QOPENGLF_APIENTRYP GetVertexAttribiv)(GLuint index, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetVertexAttribfv)(GLuint index, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetVertexAttribdv)(GLuint index, GLenum pname, GLdouble *params); + void(QOPENGLF_APIENTRYP GetUniformiv)(GLuint program, GLint location, GLint *params); + void(QOPENGLF_APIENTRYP GetUniformfv)(GLuint program, GLint location, GLfloat *params); + GLint(QOPENGLF_APIENTRYP GetUniformLocation)(GLuint program, const GLchar *name); + void(QOPENGLF_APIENTRYP GetShaderSource)(GLuint shader, GLsizei bufSize, GLsizei *length, + GLchar *source); + void(QOPENGLF_APIENTRYP GetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei *length, + GLchar *infoLog); + void(QOPENGLF_APIENTRYP GetShaderiv)(GLuint shader, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetProgramInfoLog)(GLuint program, GLsizei bufSize, GLsizei *length, + GLchar *infoLog); + void(QOPENGLF_APIENTRYP GetProgramiv)(GLuint program, GLenum pname, GLint *params); + GLint(QOPENGLF_APIENTRYP GetAttribLocation)(GLuint program, const GLchar *name); + void(QOPENGLF_APIENTRYP GetAttachedShaders)(GLuint program, GLsizei maxCount, GLsizei *count, + GLuint *obj); + void(QOPENGLF_APIENTRYP GetActiveUniform)(GLuint program, GLuint index, GLsizei bufSize, + GLsizei *length, GLint *size, GLenum *type, + GLchar *name); + void(QOPENGLF_APIENTRYP GetActiveAttrib)(GLuint program, GLuint index, GLsizei bufSize, + GLsizei *length, GLint *size, GLenum *type, + GLchar *name); + void(QOPENGLF_APIENTRYP EnableVertexAttribArray)(GLuint index); + void(QOPENGLF_APIENTRYP DisableVertexAttribArray)(GLuint index); + void(QOPENGLF_APIENTRYP DetachShader)(GLuint program, GLuint shader); + void(QOPENGLF_APIENTRYP DeleteShader)(GLuint shader); + void(QOPENGLF_APIENTRYP DeleteProgram)(GLuint program); + GLuint(QOPENGLF_APIENTRYP CreateShader)(GLenum type); + GLuint(QOPENGLF_APIENTRYP CreateProgram)(); + void(QOPENGLF_APIENTRYP CompileShader)(GLuint shader); + void(QOPENGLF_APIENTRYP BindAttribLocation)(GLuint program, GLuint index, const GLchar *name); + void(QOPENGLF_APIENTRYP AttachShader)(GLuint program, GLuint shader); + void(QOPENGLF_APIENTRYP StencilMaskSeparate)(GLenum face, GLuint mask); + void(QOPENGLF_APIENTRYP StencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask); + void(QOPENGLF_APIENTRYP StencilOpSeparate)(GLenum face, GLenum sfail, GLenum dpfail, + GLenum dppass); + void(QOPENGLF_APIENTRYP DrawBuffers)(GLsizei n, const GLenum *bufs); + void(QOPENGLF_APIENTRYP BlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha); }; -class QOpenGLFunctions_2_1_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_2_1_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_2_1_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 2.1 core functions - void (QOPENGLF_APIENTRYP UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - + void(QOPENGLF_APIENTRYP UniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP UniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP UniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP UniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP UniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP UniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); }; -class QOpenGLFunctions_3_0_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_3_0_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_3_0_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 3.0 core functions - GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array); - void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); - void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); - void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); - void (QOPENGLF_APIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length); - GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); - void (QOPENGLF_APIENTRYP FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); - void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target); - void (QOPENGLF_APIENTRYP GetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP FramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); - void (QOPENGLF_APIENTRYP FramebufferTexture3D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); - void (QOPENGLF_APIENTRYP FramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); - void (QOPENGLF_APIENTRYP FramebufferTexture1D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); - GLenum (QOPENGLF_APIENTRYP CheckFramebufferStatus)(GLenum target); - void (QOPENGLF_APIENTRYP GenFramebuffers)(GLsizei n, GLuint *framebuffers); - void (QOPENGLF_APIENTRYP DeleteFramebuffers)(GLsizei n, const GLuint *framebuffers); - void (QOPENGLF_APIENTRYP BindFramebuffer)(GLenum target, GLuint framebuffer); - GLboolean (QOPENGLF_APIENTRYP IsFramebuffer)(GLuint framebuffer); - void (QOPENGLF_APIENTRYP GetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP RenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP GenRenderbuffers)(GLsizei n, GLuint *renderbuffers); - void (QOPENGLF_APIENTRYP DeleteRenderbuffers)(GLsizei n, const GLuint *renderbuffers); - void (QOPENGLF_APIENTRYP BindRenderbuffer)(GLenum target, GLuint renderbuffer); - GLboolean (QOPENGLF_APIENTRYP IsRenderbuffer)(GLuint renderbuffer); - const GLubyte * (QOPENGLF_APIENTRYP GetStringi)(GLenum name, GLuint index); - void (QOPENGLF_APIENTRYP ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); - void (QOPENGLF_APIENTRYP ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value); - void (QOPENGLF_APIENTRYP ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value); - void (QOPENGLF_APIENTRYP ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value); - void (QOPENGLF_APIENTRYP GetTexParameterIuiv)(GLenum target, GLenum pname, GLuint *params); - void (QOPENGLF_APIENTRYP GetTexParameterIiv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP TexParameterIuiv)(GLenum target, GLenum pname, const GLuint *params); - void (QOPENGLF_APIENTRYP TexParameterIiv)(GLenum target, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP Uniform4uiv)(GLint location, GLsizei count, const GLuint *value); - void (QOPENGLF_APIENTRYP Uniform3uiv)(GLint location, GLsizei count, const GLuint *value); - void (QOPENGLF_APIENTRYP Uniform2uiv)(GLint location, GLsizei count, const GLuint *value); - void (QOPENGLF_APIENTRYP Uniform1uiv)(GLint location, GLsizei count, const GLuint *value); - void (QOPENGLF_APIENTRYP Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); - void (QOPENGLF_APIENTRYP Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2); - void (QOPENGLF_APIENTRYP Uniform2ui)(GLint location, GLuint v0, GLuint v1); - void (QOPENGLF_APIENTRYP Uniform1ui)(GLint location, GLuint v0); - GLint (QOPENGLF_APIENTRYP GetFragDataLocation)(GLuint program, const GLchar *name); - void (QOPENGLF_APIENTRYP BindFragDataLocation)(GLuint program, GLuint color, const GLchar *name); - void (QOPENGLF_APIENTRYP GetUniformuiv)(GLuint program, GLint location, GLuint *params); - void (QOPENGLF_APIENTRYP GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params); - void (QOPENGLF_APIENTRYP GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP VertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP EndConditionalRender)(); - void (QOPENGLF_APIENTRYP BeginConditionalRender)(GLuint id, GLenum mode); - void (QOPENGLF_APIENTRYP ClampColor)(GLenum target, GLenum clamp); - void (QOPENGLF_APIENTRYP GetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); - void (QOPENGLF_APIENTRYP TransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode); - void (QOPENGLF_APIENTRYP BindBufferBase)(GLenum target, GLuint index, GLuint buffer); - void (QOPENGLF_APIENTRYP BindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); - void (QOPENGLF_APIENTRYP EndTransformFeedback)(); - void (QOPENGLF_APIENTRYP BeginTransformFeedback)(GLenum primitiveMode); - GLboolean (QOPENGLF_APIENTRYP IsEnabledi)(GLenum target, GLuint index); - void (QOPENGLF_APIENTRYP Disablei)(GLenum target, GLuint index); - void (QOPENGLF_APIENTRYP Enablei)(GLenum target, GLuint index); - void (QOPENGLF_APIENTRYP GetIntegeri_v)(GLenum target, GLuint index, GLint *data); - void (QOPENGLF_APIENTRYP GetBooleani_v)(GLenum target, GLuint index, GLboolean *data); - void (QOPENGLF_APIENTRYP ColorMaski)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); - + GLboolean(QOPENGLF_APIENTRYP IsVertexArray)(GLuint array); + void(QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); + void(QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void(QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); + void(QOPENGLF_APIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, + GLsizeiptr length); + GLvoid *(QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, + GLbitfield access); + void(QOPENGLF_APIENTRYP FramebufferTextureLayer)(GLenum target, GLenum attachment, + GLuint texture, GLint level, GLint layer); + void(QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height); + void(QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); + void(QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target); + void(QOPENGLF_APIENTRYP GetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, + GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP FramebufferRenderbuffer)(GLenum target, GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); + void(QOPENGLF_APIENTRYP FramebufferTexture3D)(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level, + GLint zoffset); + void(QOPENGLF_APIENTRYP FramebufferTexture2D)(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level); + void(QOPENGLF_APIENTRYP FramebufferTexture1D)(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level); + GLenum(QOPENGLF_APIENTRYP CheckFramebufferStatus)(GLenum target); + void(QOPENGLF_APIENTRYP GenFramebuffers)(GLsizei n, GLuint *framebuffers); + void(QOPENGLF_APIENTRYP DeleteFramebuffers)(GLsizei n, const GLuint *framebuffers); + void(QOPENGLF_APIENTRYP BindFramebuffer)(GLenum target, GLuint framebuffer); + GLboolean(QOPENGLF_APIENTRYP IsFramebuffer)(GLuint framebuffer); + void(QOPENGLF_APIENTRYP GetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP RenderbufferStorage)(GLenum target, GLenum internalformat, + GLsizei width, GLsizei height); + void(QOPENGLF_APIENTRYP GenRenderbuffers)(GLsizei n, GLuint *renderbuffers); + void(QOPENGLF_APIENTRYP DeleteRenderbuffers)(GLsizei n, const GLuint *renderbuffers); + void(QOPENGLF_APIENTRYP BindRenderbuffer)(GLenum target, GLuint renderbuffer); + GLboolean(QOPENGLF_APIENTRYP IsRenderbuffer)(GLuint renderbuffer); + const GLubyte *(QOPENGLF_APIENTRYP GetStringi)(GLenum name, GLuint index); + void(QOPENGLF_APIENTRYP ClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, + GLint stencil); + void(QOPENGLF_APIENTRYP ClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value); + void(QOPENGLF_APIENTRYP ClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value); + void(QOPENGLF_APIENTRYP ClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value); + void(QOPENGLF_APIENTRYP GetTexParameterIuiv)(GLenum target, GLenum pname, GLuint *params); + void(QOPENGLF_APIENTRYP GetTexParameterIiv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP TexParameterIuiv)(GLenum target, GLenum pname, const GLuint *params); + void(QOPENGLF_APIENTRYP TexParameterIiv)(GLenum target, GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP Uniform4uiv)(GLint location, GLsizei count, const GLuint *value); + void(QOPENGLF_APIENTRYP Uniform3uiv)(GLint location, GLsizei count, const GLuint *value); + void(QOPENGLF_APIENTRYP Uniform2uiv)(GLint location, GLsizei count, const GLuint *value); + void(QOPENGLF_APIENTRYP Uniform1uiv)(GLint location, GLsizei count, const GLuint *value); + void(QOPENGLF_APIENTRYP Uniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void(QOPENGLF_APIENTRYP Uniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2); + void(QOPENGLF_APIENTRYP Uniform2ui)(GLint location, GLuint v0, GLuint v1); + void(QOPENGLF_APIENTRYP Uniform1ui)(GLint location, GLuint v0); + GLint(QOPENGLF_APIENTRYP GetFragDataLocation)(GLuint program, const GLchar *name); + void(QOPENGLF_APIENTRYP BindFragDataLocation)(GLuint program, GLuint color, const GLchar *name); + void(QOPENGLF_APIENTRYP GetUniformuiv)(GLuint program, GLint location, GLuint *params); + void(QOPENGLF_APIENTRYP GetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params); + void(QOPENGLF_APIENTRYP GetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP VertexAttribIPointer)(GLuint index, GLint size, GLenum type, + GLsizei stride, const GLvoid *pointer); + void(QOPENGLF_APIENTRYP EndConditionalRender)(); + void(QOPENGLF_APIENTRYP BeginConditionalRender)(GLuint id, GLenum mode); + void(QOPENGLF_APIENTRYP ClampColor)(GLenum target, GLenum clamp); + void(QOPENGLF_APIENTRYP GetTransformFeedbackVarying)(GLuint program, GLuint index, + GLsizei bufSize, GLsizei *length, + GLsizei *size, GLenum *type, GLchar *name); + void(QOPENGLF_APIENTRYP TransformFeedbackVaryings)(GLuint program, GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode); + void(QOPENGLF_APIENTRYP BindBufferBase)(GLenum target, GLuint index, GLuint buffer); + void(QOPENGLF_APIENTRYP BindBufferRange)(GLenum target, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size); + void(QOPENGLF_APIENTRYP EndTransformFeedback)(); + void(QOPENGLF_APIENTRYP BeginTransformFeedback)(GLenum primitiveMode); + GLboolean(QOPENGLF_APIENTRYP IsEnabledi)(GLenum target, GLuint index); + void(QOPENGLF_APIENTRYP Disablei)(GLenum target, GLuint index); + void(QOPENGLF_APIENTRYP Enablei)(GLenum target, GLuint index); + void(QOPENGLF_APIENTRYP GetIntegeri_v)(GLenum target, GLuint index, GLint *data); + void(QOPENGLF_APIENTRYP GetBooleani_v)(GLenum target, GLuint index, GLboolean *data); + void(QOPENGLF_APIENTRYP ColorMaski)(GLuint index, GLboolean r, GLboolean g, GLboolean b, + GLboolean a); }; -class QOpenGLFunctions_3_1_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_3_1_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_3_1_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 3.1 core functions - void (QOPENGLF_APIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); - void (QOPENGLF_APIENTRYP UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); - void (QOPENGLF_APIENTRYP GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); - void (QOPENGLF_APIENTRYP GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); - GLuint (QOPENGLF_APIENTRYP GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName); - void (QOPENGLF_APIENTRYP GetActiveUniformName)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); - void (QOPENGLF_APIENTRYP GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices); - void (QOPENGLF_APIENTRYP PrimitiveRestartIndex)(GLuint index); - void (QOPENGLF_APIENTRYP TexBuffer)(GLenum target, GLenum internalformat, GLuint buffer); - void (QOPENGLF_APIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount); - void (QOPENGLF_APIENTRYP DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); - + void(QOPENGLF_APIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size); + void(QOPENGLF_APIENTRYP UniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, + GLuint uniformBlockBinding); + void(QOPENGLF_APIENTRYP GetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, + GLsizei bufSize, GLsizei *length, + GLchar *uniformBlockName); + void(QOPENGLF_APIENTRYP GetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, + GLenum pname, GLint *params); + GLuint(QOPENGLF_APIENTRYP GetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName); + void(QOPENGLF_APIENTRYP GetActiveUniformName)(GLuint program, GLuint uniformIndex, + GLsizei bufSize, GLsizei *length, + GLchar *uniformName); + void(QOPENGLF_APIENTRYP GetActiveUniformsiv)(GLuint program, GLsizei uniformCount, + const GLuint *uniformIndices, GLenum pname, + GLint *params); + void(QOPENGLF_APIENTRYP GetUniformIndices)(GLuint program, GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices); + void(QOPENGLF_APIENTRYP PrimitiveRestartIndex)(GLuint index); + void(QOPENGLF_APIENTRYP TexBuffer)(GLenum target, GLenum internalformat, GLuint buffer); + void(QOPENGLF_APIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei instancecount); + void(QOPENGLF_APIENTRYP DrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, + GLsizei instancecount); }; -class QOpenGLFunctions_3_2_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_3_2_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_3_2_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 3.2 core functions - void (QOPENGLF_APIENTRYP SampleMaski)(GLuint index, GLbitfield mask); - void (QOPENGLF_APIENTRYP GetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val); - void (QOPENGLF_APIENTRYP TexImage3DMultisample)(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - void (QOPENGLF_APIENTRYP TexImage2DMultisample)(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); - void (QOPENGLF_APIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); - void (QOPENGLF_APIENTRYP GetInteger64v)(GLenum pname, GLint64 *params); - void (QOPENGLF_APIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); - GLenum (QOPENGLF_APIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); - void (QOPENGLF_APIENTRYP DeleteSync)(GLsync sync); - GLboolean (QOPENGLF_APIENTRYP IsSync)(GLsync sync); - GLsync (QOPENGLF_APIENTRYP FenceSync)(GLenum condition, GLbitfield flags); - void (QOPENGLF_APIENTRYP ProvokingVertex)(GLenum mode); - void (QOPENGLF_APIENTRYP MultiDrawElementsBaseVertex)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint *basevertex); - void (QOPENGLF_APIENTRYP DrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount, GLint basevertex); - void (QOPENGLF_APIENTRYP DrawRangeElementsBaseVertex)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); - void (QOPENGLF_APIENTRYP DrawElementsBaseVertex)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); - void (QOPENGLF_APIENTRYP FramebufferTexture)(GLenum target, GLenum attachment, GLuint texture, GLint level); - void (QOPENGLF_APIENTRYP GetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params); - void (QOPENGLF_APIENTRYP GetInteger64i_v)(GLenum target, GLuint index, GLint64 *data); - + void(QOPENGLF_APIENTRYP SampleMaski)(GLuint index, GLbitfield mask); + void(QOPENGLF_APIENTRYP GetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val); + void(QOPENGLF_APIENTRYP TexImage3DMultisample)(GLenum target, GLsizei samples, + GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations); + void(QOPENGLF_APIENTRYP TexImage2DMultisample)(GLenum target, GLsizei samples, + GLint internalformat, GLsizei width, + GLsizei height, GLboolean fixedsamplelocations); + void(QOPENGLF_APIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, + GLint *values); + void(QOPENGLF_APIENTRYP GetInteger64v)(GLenum pname, GLint64 *params); + void(QOPENGLF_APIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + GLenum(QOPENGLF_APIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); + void(QOPENGLF_APIENTRYP DeleteSync)(GLsync sync); + GLboolean(QOPENGLF_APIENTRYP IsSync)(GLsync sync); + GLsync(QOPENGLF_APIENTRYP FenceSync)(GLenum condition, GLbitfield flags); + void(QOPENGLF_APIENTRYP ProvokingVertex)(GLenum mode); + void(QOPENGLF_APIENTRYP MultiDrawElementsBaseVertex)(GLenum mode, const GLsizei *count, + GLenum type, const GLvoid *const *indices, + GLsizei drawcount, + const GLint *basevertex); + void(QOPENGLF_APIENTRYP DrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices, + GLsizei instancecount, + GLint basevertex); + void(QOPENGLF_APIENTRYP DrawRangeElementsBaseVertex)(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex); + void(QOPENGLF_APIENTRYP DrawElementsBaseVertex)(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex); + void(QOPENGLF_APIENTRYP FramebufferTexture)(GLenum target, GLenum attachment, GLuint texture, + GLint level); + void(QOPENGLF_APIENTRYP GetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params); + void(QOPENGLF_APIENTRYP GetInteger64i_v)(GLenum target, GLuint index, GLint64 *data); }; -class QOpenGLFunctions_3_3_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_3_3_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_3_3_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 3.3 core functions - void (QOPENGLF_APIENTRYP VertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); - void (QOPENGLF_APIENTRYP VertexAttribP4ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value); - void (QOPENGLF_APIENTRYP VertexAttribP3uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); - void (QOPENGLF_APIENTRYP VertexAttribP3ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value); - void (QOPENGLF_APIENTRYP VertexAttribP2uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); - void (QOPENGLF_APIENTRYP VertexAttribP2ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value); - void (QOPENGLF_APIENTRYP VertexAttribP1uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); - void (QOPENGLF_APIENTRYP VertexAttribP1ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value); - void (QOPENGLF_APIENTRYP SecondaryColorP3uiv)(GLenum type, const GLuint *color); - void (QOPENGLF_APIENTRYP SecondaryColorP3ui)(GLenum type, GLuint color); - void (QOPENGLF_APIENTRYP ColorP4uiv)(GLenum type, const GLuint *color); - void (QOPENGLF_APIENTRYP ColorP4ui)(GLenum type, GLuint color); - void (QOPENGLF_APIENTRYP ColorP3uiv)(GLenum type, const GLuint *color); - void (QOPENGLF_APIENTRYP ColorP3ui)(GLenum type, GLuint color); - void (QOPENGLF_APIENTRYP NormalP3uiv)(GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP NormalP3ui)(GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP MultiTexCoordP4uiv)(GLenum texture, GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP MultiTexCoordP4ui)(GLenum texture, GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP MultiTexCoordP3uiv)(GLenum texture, GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP MultiTexCoordP3ui)(GLenum texture, GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP MultiTexCoordP2uiv)(GLenum texture, GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP MultiTexCoordP2ui)(GLenum texture, GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP MultiTexCoordP1uiv)(GLenum texture, GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP MultiTexCoordP1ui)(GLenum texture, GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP TexCoordP4uiv)(GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP TexCoordP4ui)(GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP TexCoordP3uiv)(GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP TexCoordP3ui)(GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP TexCoordP2uiv)(GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP TexCoordP2ui)(GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP TexCoordP1uiv)(GLenum type, const GLuint *coords); - void (QOPENGLF_APIENTRYP TexCoordP1ui)(GLenum type, GLuint coords); - void (QOPENGLF_APIENTRYP VertexP4uiv)(GLenum type, const GLuint *value); - void (QOPENGLF_APIENTRYP VertexP4ui)(GLenum type, GLuint value); - void (QOPENGLF_APIENTRYP VertexP3uiv)(GLenum type, const GLuint *value); - void (QOPENGLF_APIENTRYP VertexP3ui)(GLenum type, GLuint value); - void (QOPENGLF_APIENTRYP VertexP2uiv)(GLenum type, const GLuint *value); - void (QOPENGLF_APIENTRYP VertexP2ui)(GLenum type, GLuint value); - void (QOPENGLF_APIENTRYP GetQueryObjectui64v)(GLuint id, GLenum pname, GLuint64 *params); - void (QOPENGLF_APIENTRYP GetQueryObjecti64v)(GLuint id, GLenum pname, GLint64 *params); - void (QOPENGLF_APIENTRYP QueryCounter)(GLuint id, GLenum target); - void (QOPENGLF_APIENTRYP GetSamplerParameterIuiv)(GLuint sampler, GLenum pname, GLuint *params); - void (QOPENGLF_APIENTRYP GetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetSamplerParameterIiv)(GLuint sampler, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP SamplerParameterIuiv)(GLuint sampler, GLenum pname, const GLuint *param); - void (QOPENGLF_APIENTRYP SamplerParameterIiv)(GLuint sampler, GLenum pname, const GLint *param); - void (QOPENGLF_APIENTRYP SamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param); - void (QOPENGLF_APIENTRYP SamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP SamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param); - void (QOPENGLF_APIENTRYP SamplerParameteri)(GLuint sampler, GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP BindSampler)(GLuint unit, GLuint sampler); - GLboolean (QOPENGLF_APIENTRYP IsSampler)(GLuint sampler); - void (QOPENGLF_APIENTRYP DeleteSamplers)(GLsizei count, const GLuint *samplers); - void (QOPENGLF_APIENTRYP GenSamplers)(GLsizei count, GLuint *samplers); - GLint (QOPENGLF_APIENTRYP GetFragDataIndex)(GLuint program, const GLchar *name); - void (QOPENGLF_APIENTRYP BindFragDataLocationIndexed)(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); - void (QOPENGLF_APIENTRYP VertexAttribDivisor)(GLuint index, GLuint divisor); - + void(QOPENGLF_APIENTRYP VertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized, + const GLuint *value); + void(QOPENGLF_APIENTRYP VertexAttribP4ui)(GLuint index, GLenum type, GLboolean normalized, + GLuint value); + void(QOPENGLF_APIENTRYP VertexAttribP3uiv)(GLuint index, GLenum type, GLboolean normalized, + const GLuint *value); + void(QOPENGLF_APIENTRYP VertexAttribP3ui)(GLuint index, GLenum type, GLboolean normalized, + GLuint value); + void(QOPENGLF_APIENTRYP VertexAttribP2uiv)(GLuint index, GLenum type, GLboolean normalized, + const GLuint *value); + void(QOPENGLF_APIENTRYP VertexAttribP2ui)(GLuint index, GLenum type, GLboolean normalized, + GLuint value); + void(QOPENGLF_APIENTRYP VertexAttribP1uiv)(GLuint index, GLenum type, GLboolean normalized, + const GLuint *value); + void(QOPENGLF_APIENTRYP VertexAttribP1ui)(GLuint index, GLenum type, GLboolean normalized, + GLuint value); + void(QOPENGLF_APIENTRYP SecondaryColorP3uiv)(GLenum type, const GLuint *color); + void(QOPENGLF_APIENTRYP SecondaryColorP3ui)(GLenum type, GLuint color); + void(QOPENGLF_APIENTRYP ColorP4uiv)(GLenum type, const GLuint *color); + void(QOPENGLF_APIENTRYP ColorP4ui)(GLenum type, GLuint color); + void(QOPENGLF_APIENTRYP ColorP3uiv)(GLenum type, const GLuint *color); + void(QOPENGLF_APIENTRYP ColorP3ui)(GLenum type, GLuint color); + void(QOPENGLF_APIENTRYP NormalP3uiv)(GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP NormalP3ui)(GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP MultiTexCoordP4uiv)(GLenum texture, GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP MultiTexCoordP4ui)(GLenum texture, GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP MultiTexCoordP3uiv)(GLenum texture, GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP MultiTexCoordP3ui)(GLenum texture, GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP MultiTexCoordP2uiv)(GLenum texture, GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP MultiTexCoordP2ui)(GLenum texture, GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP MultiTexCoordP1uiv)(GLenum texture, GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP MultiTexCoordP1ui)(GLenum texture, GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP TexCoordP4uiv)(GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP TexCoordP4ui)(GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP TexCoordP3uiv)(GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP TexCoordP3ui)(GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP TexCoordP2uiv)(GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP TexCoordP2ui)(GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP TexCoordP1uiv)(GLenum type, const GLuint *coords); + void(QOPENGLF_APIENTRYP TexCoordP1ui)(GLenum type, GLuint coords); + void(QOPENGLF_APIENTRYP VertexP4uiv)(GLenum type, const GLuint *value); + void(QOPENGLF_APIENTRYP VertexP4ui)(GLenum type, GLuint value); + void(QOPENGLF_APIENTRYP VertexP3uiv)(GLenum type, const GLuint *value); + void(QOPENGLF_APIENTRYP VertexP3ui)(GLenum type, GLuint value); + void(QOPENGLF_APIENTRYP VertexP2uiv)(GLenum type, const GLuint *value); + void(QOPENGLF_APIENTRYP VertexP2ui)(GLenum type, GLuint value); + void(QOPENGLF_APIENTRYP GetQueryObjectui64v)(GLuint id, GLenum pname, GLuint64 *params); + void(QOPENGLF_APIENTRYP GetQueryObjecti64v)(GLuint id, GLenum pname, GLint64 *params); + void(QOPENGLF_APIENTRYP QueryCounter)(GLuint id, GLenum target); + void(QOPENGLF_APIENTRYP GetSamplerParameterIuiv)(GLuint sampler, GLenum pname, GLuint *params); + void(QOPENGLF_APIENTRYP GetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetSamplerParameterIiv)(GLuint sampler, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP SamplerParameterIuiv)(GLuint sampler, GLenum pname, + const GLuint *param); + void(QOPENGLF_APIENTRYP SamplerParameterIiv)(GLuint sampler, GLenum pname, const GLint *param); + void(QOPENGLF_APIENTRYP SamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param); + void(QOPENGLF_APIENTRYP SamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP SamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param); + void(QOPENGLF_APIENTRYP SamplerParameteri)(GLuint sampler, GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP BindSampler)(GLuint unit, GLuint sampler); + GLboolean(QOPENGLF_APIENTRYP IsSampler)(GLuint sampler); + void(QOPENGLF_APIENTRYP DeleteSamplers)(GLsizei count, const GLuint *samplers); + void(QOPENGLF_APIENTRYP GenSamplers)(GLsizei count, GLuint *samplers); + GLint(QOPENGLF_APIENTRYP GetFragDataIndex)(GLuint program, const GLchar *name); + void(QOPENGLF_APIENTRYP BindFragDataLocationIndexed)(GLuint program, GLuint colorNumber, + GLuint index, const GLchar *name); + void(QOPENGLF_APIENTRYP VertexAttribDivisor)(GLuint index, GLuint divisor); }; -class QOpenGLFunctions_4_0_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_4_0_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_4_0_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 4.0 core functions - void (QOPENGLF_APIENTRYP GetQueryIndexediv)(GLenum target, GLuint index, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP EndQueryIndexed)(GLenum target, GLuint index); - void (QOPENGLF_APIENTRYP BeginQueryIndexed)(GLenum target, GLuint index, GLuint id); - void (QOPENGLF_APIENTRYP DrawTransformFeedbackStream)(GLenum mode, GLuint id, GLuint stream); - void (QOPENGLF_APIENTRYP DrawTransformFeedback)(GLenum mode, GLuint id); - void (QOPENGLF_APIENTRYP ResumeTransformFeedback)(); - void (QOPENGLF_APIENTRYP PauseTransformFeedback)(); - GLboolean (QOPENGLF_APIENTRYP IsTransformFeedback)(GLuint id); - void (QOPENGLF_APIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint *ids); - void (QOPENGLF_APIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint *ids); - void (QOPENGLF_APIENTRYP BindTransformFeedback)(GLenum target, GLuint id); - void (QOPENGLF_APIENTRYP PatchParameterfv)(GLenum pname, const GLfloat *values); - void (QOPENGLF_APIENTRYP PatchParameteri)(GLenum pname, GLint value); - void (QOPENGLF_APIENTRYP GetProgramStageiv)(GLuint program, GLenum shadertype, GLenum pname, GLint *values); - void (QOPENGLF_APIENTRYP GetUniformSubroutineuiv)(GLenum shadertype, GLint location, GLuint *params); - void (QOPENGLF_APIENTRYP UniformSubroutinesuiv)(GLenum shadertype, GLsizei count, const GLuint *indices); - void (QOPENGLF_APIENTRYP GetActiveSubroutineName)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); - void (QOPENGLF_APIENTRYP GetActiveSubroutineUniformName)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); - void (QOPENGLF_APIENTRYP GetActiveSubroutineUniformiv)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); - GLuint (QOPENGLF_APIENTRYP GetSubroutineIndex)(GLuint program, GLenum shadertype, const GLchar *name); - GLint (QOPENGLF_APIENTRYP GetSubroutineUniformLocation)(GLuint program, GLenum shadertype, const GLchar *name); - void (QOPENGLF_APIENTRYP GetUniformdv)(GLuint program, GLint location, GLdouble *params); - void (QOPENGLF_APIENTRYP UniformMatrix4x3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP UniformMatrix4x2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP UniformMatrix3x4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP UniformMatrix3x2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP UniformMatrix2x4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP UniformMatrix2x3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP UniformMatrix4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP UniformMatrix3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP UniformMatrix2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP Uniform4dv)(GLint location, GLsizei count, const GLdouble *value); - void (QOPENGLF_APIENTRYP Uniform3dv)(GLint location, GLsizei count, const GLdouble *value); - void (QOPENGLF_APIENTRYP Uniform2dv)(GLint location, GLsizei count, const GLdouble *value); - void (QOPENGLF_APIENTRYP Uniform1dv)(GLint location, GLsizei count, const GLdouble *value); - void (QOPENGLF_APIENTRYP Uniform4d)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); - void (QOPENGLF_APIENTRYP Uniform3d)(GLint location, GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP Uniform2d)(GLint location, GLdouble x, GLdouble y); - void (QOPENGLF_APIENTRYP Uniform1d)(GLint location, GLdouble x); - void (QOPENGLF_APIENTRYP DrawElementsIndirect)(GLenum mode, GLenum type, const GLvoid *indirect); - void (QOPENGLF_APIENTRYP DrawArraysIndirect)(GLenum mode, const GLvoid *indirect); - void (QOPENGLF_APIENTRYP BlendFuncSeparatei)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); - void (QOPENGLF_APIENTRYP BlendFunci)(GLuint buf, GLenum src, GLenum dst); - void (QOPENGLF_APIENTRYP BlendEquationSeparatei)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); - void (QOPENGLF_APIENTRYP BlendEquationi)(GLuint buf, GLenum mode); - void (QOPENGLF_APIENTRYP MinSampleShading)(GLfloat value); - + void(QOPENGLF_APIENTRYP GetQueryIndexediv)(GLenum target, GLuint index, GLenum pname, + GLint *params); + void(QOPENGLF_APIENTRYP EndQueryIndexed)(GLenum target, GLuint index); + void(QOPENGLF_APIENTRYP BeginQueryIndexed)(GLenum target, GLuint index, GLuint id); + void(QOPENGLF_APIENTRYP DrawTransformFeedbackStream)(GLenum mode, GLuint id, GLuint stream); + void(QOPENGLF_APIENTRYP DrawTransformFeedback)(GLenum mode, GLuint id); + void(QOPENGLF_APIENTRYP ResumeTransformFeedback)(); + void(QOPENGLF_APIENTRYP PauseTransformFeedback)(); + GLboolean(QOPENGLF_APIENTRYP IsTransformFeedback)(GLuint id); + void(QOPENGLF_APIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint *ids); + void(QOPENGLF_APIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint *ids); + void(QOPENGLF_APIENTRYP BindTransformFeedback)(GLenum target, GLuint id); + void(QOPENGLF_APIENTRYP PatchParameterfv)(GLenum pname, const GLfloat *values); + void(QOPENGLF_APIENTRYP PatchParameteri)(GLenum pname, GLint value); + void(QOPENGLF_APIENTRYP GetProgramStageiv)(GLuint program, GLenum shadertype, GLenum pname, + GLint *values); + void(QOPENGLF_APIENTRYP GetUniformSubroutineuiv)(GLenum shadertype, GLint location, + GLuint *params); + void(QOPENGLF_APIENTRYP UniformSubroutinesuiv)(GLenum shadertype, GLsizei count, + const GLuint *indices); + void(QOPENGLF_APIENTRYP GetActiveSubroutineName)(GLuint program, GLenum shadertype, + GLuint index, GLsizei bufsize, GLsizei *length, + GLchar *name); + void(QOPENGLF_APIENTRYP GetActiveSubroutineUniformName)(GLuint program, GLenum shadertype, + GLuint index, GLsizei bufsize, + GLsizei *length, GLchar *name); + void(QOPENGLF_APIENTRYP GetActiveSubroutineUniformiv)(GLuint program, GLenum shadertype, + GLuint index, GLenum pname, + GLint *values); + GLuint(QOPENGLF_APIENTRYP GetSubroutineIndex)(GLuint program, GLenum shadertype, + const GLchar *name); + GLint(QOPENGLF_APIENTRYP GetSubroutineUniformLocation)(GLuint program, GLenum shadertype, + const GLchar *name); + void(QOPENGLF_APIENTRYP GetUniformdv)(GLuint program, GLint location, GLdouble *params); + void(QOPENGLF_APIENTRYP UniformMatrix4x3dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP UniformMatrix4x2dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP UniformMatrix3x4dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP UniformMatrix3x2dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP UniformMatrix2x4dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP UniformMatrix2x3dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP UniformMatrix4dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP UniformMatrix3dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP UniformMatrix2dv)(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP Uniform4dv)(GLint location, GLsizei count, const GLdouble *value); + void(QOPENGLF_APIENTRYP Uniform3dv)(GLint location, GLsizei count, const GLdouble *value); + void(QOPENGLF_APIENTRYP Uniform2dv)(GLint location, GLsizei count, const GLdouble *value); + void(QOPENGLF_APIENTRYP Uniform1dv)(GLint location, GLsizei count, const GLdouble *value); + void(QOPENGLF_APIENTRYP Uniform4d)(GLint location, GLdouble x, GLdouble y, GLdouble z, + GLdouble w); + void(QOPENGLF_APIENTRYP Uniform3d)(GLint location, GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP Uniform2d)(GLint location, GLdouble x, GLdouble y); + void(QOPENGLF_APIENTRYP Uniform1d)(GLint location, GLdouble x); + void(QOPENGLF_APIENTRYP DrawElementsIndirect)(GLenum mode, GLenum type, const GLvoid *indirect); + void(QOPENGLF_APIENTRYP DrawArraysIndirect)(GLenum mode, const GLvoid *indirect); + void(QOPENGLF_APIENTRYP BlendFuncSeparatei)(GLuint buf, GLenum srcRGB, GLenum dstRGB, + GLenum srcAlpha, GLenum dstAlpha); + void(QOPENGLF_APIENTRYP BlendFunci)(GLuint buf, GLenum src, GLenum dst); + void(QOPENGLF_APIENTRYP BlendEquationSeparatei)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); + void(QOPENGLF_APIENTRYP BlendEquationi)(GLuint buf, GLenum mode); + void(QOPENGLF_APIENTRYP MinSampleShading)(GLfloat value); }; -class QOpenGLFunctions_4_1_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_4_1_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_4_1_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 4.1 core functions - void (QOPENGLF_APIENTRYP GetDoublei_v)(GLenum target, GLuint index, GLdouble *data); - void (QOPENGLF_APIENTRYP GetFloati_v)(GLenum target, GLuint index, GLfloat *data); - void (QOPENGLF_APIENTRYP DepthRangeIndexed)(GLuint index, GLdouble n, GLdouble f); - void (QOPENGLF_APIENTRYP DepthRangeArrayv)(GLuint first, GLsizei count, const GLdouble *v); - void (QOPENGLF_APIENTRYP ScissorIndexedv)(GLuint index, const GLint *v); - void (QOPENGLF_APIENTRYP ScissorIndexed)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP ScissorArrayv)(GLuint first, GLsizei count, const GLint *v); - void (QOPENGLF_APIENTRYP ViewportIndexedfv)(GLuint index, const GLfloat *v); - void (QOPENGLF_APIENTRYP ViewportIndexedf)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); - void (QOPENGLF_APIENTRYP ViewportArrayv)(GLuint first, GLsizei count, const GLfloat *v); - void (QOPENGLF_APIENTRYP GetVertexAttribLdv)(GLuint index, GLenum pname, GLdouble *params); - void (QOPENGLF_APIENTRYP VertexAttribLPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP VertexAttribL4dv)(GLuint index, const GLdouble *v); - void (QOPENGLF_APIENTRYP VertexAttribL3dv)(GLuint index, const GLdouble *v); - void (QOPENGLF_APIENTRYP VertexAttribL2dv)(GLuint index, const GLdouble *v); - void (QOPENGLF_APIENTRYP VertexAttribL1dv)(GLuint index, const GLdouble *v); - void (QOPENGLF_APIENTRYP VertexAttribL4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); - void (QOPENGLF_APIENTRYP VertexAttribL3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP VertexAttribL2d)(GLuint index, GLdouble x, GLdouble y); - void (QOPENGLF_APIENTRYP VertexAttribL1d)(GLuint index, GLdouble x); - void (QOPENGLF_APIENTRYP GetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - void (QOPENGLF_APIENTRYP ValidateProgramPipeline)(GLuint pipeline); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); - void (QOPENGLF_APIENTRYP ProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); - void (QOPENGLF_APIENTRYP ProgramUniform4dv)(GLuint program, GLint location, GLsizei count, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniform4d)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); - void (QOPENGLF_APIENTRYP ProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); - void (QOPENGLF_APIENTRYP ProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint *value); - void (QOPENGLF_APIENTRYP ProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); - void (QOPENGLF_APIENTRYP ProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); - void (QOPENGLF_APIENTRYP ProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); - void (QOPENGLF_APIENTRYP ProgramUniform3dv)(GLuint program, GLint location, GLsizei count, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniform3d)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); - void (QOPENGLF_APIENTRYP ProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); - void (QOPENGLF_APIENTRYP ProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint *value); - void (QOPENGLF_APIENTRYP ProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); - void (QOPENGLF_APIENTRYP ProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); - void (QOPENGLF_APIENTRYP ProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1); - void (QOPENGLF_APIENTRYP ProgramUniform2dv)(GLuint program, GLint location, GLsizei count, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniform2d)(GLuint program, GLint location, GLdouble v0, GLdouble v1); - void (QOPENGLF_APIENTRYP ProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1); - void (QOPENGLF_APIENTRYP ProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint *value); - void (QOPENGLF_APIENTRYP ProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1); - void (QOPENGLF_APIENTRYP ProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value); - void (QOPENGLF_APIENTRYP ProgramUniform1ui)(GLuint program, GLint location, GLuint v0); - void (QOPENGLF_APIENTRYP ProgramUniform1dv)(GLuint program, GLint location, GLsizei count, const GLdouble *value); - void (QOPENGLF_APIENTRYP ProgramUniform1d)(GLuint program, GLint location, GLdouble v0); - void (QOPENGLF_APIENTRYP ProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value); - void (QOPENGLF_APIENTRYP ProgramUniform1f)(GLuint program, GLint location, GLfloat v0); - void (QOPENGLF_APIENTRYP ProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint *value); - void (QOPENGLF_APIENTRYP ProgramUniform1i)(GLuint program, GLint location, GLint v0); - void (QOPENGLF_APIENTRYP GetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params); - GLboolean (QOPENGLF_APIENTRYP IsProgramPipeline)(GLuint pipeline); - void (QOPENGLF_APIENTRYP GenProgramPipelines)(GLsizei n, GLuint *pipelines); - void (QOPENGLF_APIENTRYP DeleteProgramPipelines)(GLsizei n, const GLuint *pipelines); - void (QOPENGLF_APIENTRYP BindProgramPipeline)(GLuint pipeline); - GLuint (QOPENGLF_APIENTRYP CreateShaderProgramv)(GLenum type, GLsizei count, const GLchar* const *strings); - void (QOPENGLF_APIENTRYP ActiveShaderProgram)(GLuint pipeline, GLuint program); - void (QOPENGLF_APIENTRYP UseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program); - void (QOPENGLF_APIENTRYP ProgramParameteri)(GLuint program, GLenum pname, GLint value); - void (QOPENGLF_APIENTRYP ProgramBinary)(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length); - void (QOPENGLF_APIENTRYP GetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); - void (QOPENGLF_APIENTRYP ClearDepthf)(GLfloat dd); - void (QOPENGLF_APIENTRYP DepthRangef)(GLfloat n, GLfloat f); - void (QOPENGLF_APIENTRYP GetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); - void (QOPENGLF_APIENTRYP ShaderBinary)(GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); - void (QOPENGLF_APIENTRYP ReleaseShaderCompiler)(); - + void(QOPENGLF_APIENTRYP GetDoublei_v)(GLenum target, GLuint index, GLdouble *data); + void(QOPENGLF_APIENTRYP GetFloati_v)(GLenum target, GLuint index, GLfloat *data); + void(QOPENGLF_APIENTRYP DepthRangeIndexed)(GLuint index, GLdouble n, GLdouble f); + void(QOPENGLF_APIENTRYP DepthRangeArrayv)(GLuint first, GLsizei count, const GLdouble *v); + void(QOPENGLF_APIENTRYP ScissorIndexedv)(GLuint index, const GLint *v); + void(QOPENGLF_APIENTRYP ScissorIndexed)(GLuint index, GLint left, GLint bottom, GLsizei width, + GLsizei height); + void(QOPENGLF_APIENTRYP ScissorArrayv)(GLuint first, GLsizei count, const GLint *v); + void(QOPENGLF_APIENTRYP ViewportIndexedfv)(GLuint index, const GLfloat *v); + void(QOPENGLF_APIENTRYP ViewportIndexedf)(GLuint index, GLfloat x, GLfloat y, GLfloat w, + GLfloat h); + void(QOPENGLF_APIENTRYP ViewportArrayv)(GLuint first, GLsizei count, const GLfloat *v); + void(QOPENGLF_APIENTRYP GetVertexAttribLdv)(GLuint index, GLenum pname, GLdouble *params); + void(QOPENGLF_APIENTRYP VertexAttribLPointer)(GLuint index, GLint size, GLenum type, + GLsizei stride, const GLvoid *pointer); + void(QOPENGLF_APIENTRYP VertexAttribL4dv)(GLuint index, const GLdouble *v); + void(QOPENGLF_APIENTRYP VertexAttribL3dv)(GLuint index, const GLdouble *v); + void(QOPENGLF_APIENTRYP VertexAttribL2dv)(GLuint index, const GLdouble *v); + void(QOPENGLF_APIENTRYP VertexAttribL1dv)(GLuint index, const GLdouble *v); + void(QOPENGLF_APIENTRYP VertexAttribL4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, + GLdouble w); + void(QOPENGLF_APIENTRYP VertexAttribL3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP VertexAttribL2d)(GLuint index, GLdouble x, GLdouble y); + void(QOPENGLF_APIENTRYP VertexAttribL1d)(GLuint index, GLdouble x); + void(QOPENGLF_APIENTRYP GetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + void(QOPENGLF_APIENTRYP ValidateProgramPipeline)(GLuint pipeline); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix4x3dv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix3x4dv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix4x2dv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix2x4dv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix3x2dv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix2x3dv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix4x3fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix3x4fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix4x2fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix2x4fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix3x2fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix2x3fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix4dv)(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix3dv)(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix2dv)(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, + const GLuint *value); + void(QOPENGLF_APIENTRYP ProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, + GLuint v2, GLuint v3); + void(QOPENGLF_APIENTRYP ProgramUniform4dv)(GLuint program, GLint location, GLsizei count, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniform4d)(GLuint program, GLint location, GLdouble v0, + GLdouble v1, GLdouble v2, GLdouble v3); + void(QOPENGLF_APIENTRYP ProgramUniform4fv)(GLuint program, GLint location, GLsizei count, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniform4f)(GLuint program, GLint location, GLfloat v0, + GLfloat v1, GLfloat v2, GLfloat v3); + void(QOPENGLF_APIENTRYP ProgramUniform4iv)(GLuint program, GLint location, GLsizei count, + const GLint *value); + void(QOPENGLF_APIENTRYP ProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, + GLint v2, GLint v3); + void(QOPENGLF_APIENTRYP ProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, + const GLuint *value); + void(QOPENGLF_APIENTRYP ProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, + GLuint v2); + void(QOPENGLF_APIENTRYP ProgramUniform3dv)(GLuint program, GLint location, GLsizei count, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniform3d)(GLuint program, GLint location, GLdouble v0, + GLdouble v1, GLdouble v2); + void(QOPENGLF_APIENTRYP ProgramUniform3fv)(GLuint program, GLint location, GLsizei count, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniform3f)(GLuint program, GLint location, GLfloat v0, + GLfloat v1, GLfloat v2); + void(QOPENGLF_APIENTRYP ProgramUniform3iv)(GLuint program, GLint location, GLsizei count, + const GLint *value); + void(QOPENGLF_APIENTRYP ProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, + GLint v2); + void(QOPENGLF_APIENTRYP ProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, + const GLuint *value); + void(QOPENGLF_APIENTRYP ProgramUniform2ui)(GLuint program, GLint location, GLuint v0, + GLuint v1); + void(QOPENGLF_APIENTRYP ProgramUniform2dv)(GLuint program, GLint location, GLsizei count, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniform2d)(GLuint program, GLint location, GLdouble v0, + GLdouble v1); + void(QOPENGLF_APIENTRYP ProgramUniform2fv)(GLuint program, GLint location, GLsizei count, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniform2f)(GLuint program, GLint location, GLfloat v0, + GLfloat v1); + void(QOPENGLF_APIENTRYP ProgramUniform2iv)(GLuint program, GLint location, GLsizei count, + const GLint *value); + void(QOPENGLF_APIENTRYP ProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1); + void(QOPENGLF_APIENTRYP ProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, + const GLuint *value); + void(QOPENGLF_APIENTRYP ProgramUniform1ui)(GLuint program, GLint location, GLuint v0); + void(QOPENGLF_APIENTRYP ProgramUniform1dv)(GLuint program, GLint location, GLsizei count, + const GLdouble *value); + void(QOPENGLF_APIENTRYP ProgramUniform1d)(GLuint program, GLint location, GLdouble v0); + void(QOPENGLF_APIENTRYP ProgramUniform1fv)(GLuint program, GLint location, GLsizei count, + const GLfloat *value); + void(QOPENGLF_APIENTRYP ProgramUniform1f)(GLuint program, GLint location, GLfloat v0); + void(QOPENGLF_APIENTRYP ProgramUniform1iv)(GLuint program, GLint location, GLsizei count, + const GLint *value); + void(QOPENGLF_APIENTRYP ProgramUniform1i)(GLuint program, GLint location, GLint v0); + void(QOPENGLF_APIENTRYP GetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params); + GLboolean(QOPENGLF_APIENTRYP IsProgramPipeline)(GLuint pipeline); + void(QOPENGLF_APIENTRYP GenProgramPipelines)(GLsizei n, GLuint *pipelines); + void(QOPENGLF_APIENTRYP DeleteProgramPipelines)(GLsizei n, const GLuint *pipelines); + void(QOPENGLF_APIENTRYP BindProgramPipeline)(GLuint pipeline); + GLuint(QOPENGLF_APIENTRYP CreateShaderProgramv)(GLenum type, GLsizei count, + const GLchar *const *strings); + void(QOPENGLF_APIENTRYP ActiveShaderProgram)(GLuint pipeline, GLuint program); + void(QOPENGLF_APIENTRYP UseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program); + void(QOPENGLF_APIENTRYP ProgramParameteri)(GLuint program, GLenum pname, GLint value); + void(QOPENGLF_APIENTRYP ProgramBinary)(GLuint program, GLenum binaryFormat, + const GLvoid *binary, GLsizei length); + void(QOPENGLF_APIENTRYP GetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, + GLenum *binaryFormat, GLvoid *binary); + void(QOPENGLF_APIENTRYP ClearDepthf)(GLfloat dd); + void(QOPENGLF_APIENTRYP DepthRangef)(GLfloat n, GLfloat f); + void(QOPENGLF_APIENTRYP GetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, + GLint *range, GLint *precision); + void(QOPENGLF_APIENTRYP ShaderBinary)(GLsizei count, const GLuint *shaders, GLenum binaryformat, + const GLvoid *binary, GLsizei length); + void(QOPENGLF_APIENTRYP ReleaseShaderCompiler)(); }; -class QOpenGLFunctions_4_2_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_4_2_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_4_2_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 4.2 core functions - void (QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP TexStorage1D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -// void (QOPENGLF_APIENTRYP MemoryBarrier)(GLbitfield barriers); - void (QOPENGLF_APIENTRYP BindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); - void (QOPENGLF_APIENTRYP GetActiveAtomicCounterBufferiv)(GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); - void (QOPENGLF_APIENTRYP DrawTransformFeedbackStreamInstanced)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); - void (QOPENGLF_APIENTRYP DrawTransformFeedbackInstanced)(GLenum mode, GLuint id, GLsizei instancecount); - void (QOPENGLF_APIENTRYP DrawElementsInstancedBaseVertexBaseInstance)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); - void (QOPENGLF_APIENTRYP DrawElementsInstancedBaseInstance)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); - void (QOPENGLF_APIENTRYP DrawArraysInstancedBaseInstance)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); - + void(QOPENGLF_APIENTRYP TexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth); + void(QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height); + void(QOPENGLF_APIENTRYP TexStorage1D)(GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width); + // void (QOPENGLF_APIENTRYP MemoryBarrier)(GLbitfield barriers); + void(QOPENGLF_APIENTRYP BindImageTexture)(GLuint unit, GLuint texture, GLint level, + GLboolean layered, GLint layer, GLenum access, + GLenum format); + void(QOPENGLF_APIENTRYP GetActiveAtomicCounterBufferiv)(GLuint program, GLuint bufferIndex, + GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, + GLsizei bufSize, GLint *params); + void(QOPENGLF_APIENTRYP DrawTransformFeedbackStreamInstanced)(GLenum mode, GLuint id, + GLuint stream, + GLsizei instancecount); + void(QOPENGLF_APIENTRYP DrawTransformFeedbackInstanced)(GLenum mode, GLuint id, + GLsizei instancecount); + void(QOPENGLF_APIENTRYP DrawElementsInstancedBaseVertexBaseInstance)( + GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, + GLint basevertex, GLuint baseinstance); + void(QOPENGLF_APIENTRYP DrawElementsInstancedBaseInstance)(GLenum mode, GLsizei count, + GLenum type, const void *indices, + GLsizei instancecount, + GLuint baseinstance); + void(QOPENGLF_APIENTRYP DrawArraysInstancedBaseInstance)(GLenum mode, GLint first, + GLsizei count, GLsizei instancecount, + GLuint baseinstance); }; -class QOpenGLFunctions_4_3_CoreBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_4_3_CoreBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_4_3_CoreBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 4.3 core functions - void (QOPENGLF_APIENTRYP TexStorage3DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - void (QOPENGLF_APIENTRYP TexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); - void (QOPENGLF_APIENTRYP TexBufferRange)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); - void (QOPENGLF_APIENTRYP ShaderStorageBlockBinding)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); - GLint (QOPENGLF_APIENTRYP GetProgramResourceLocationIndex)(GLuint program, GLenum programInterface, const GLchar *name); - GLint (QOPENGLF_APIENTRYP GetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar *name); - void (QOPENGLF_APIENTRYP GetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); - void (QOPENGLF_APIENTRYP GetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); - GLuint (QOPENGLF_APIENTRYP GetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar *name); - void (QOPENGLF_APIENTRYP GetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP MultiDrawElementsIndirect)(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); - void (QOPENGLF_APIENTRYP MultiDrawArraysIndirect)(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); - void (QOPENGLF_APIENTRYP InvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP InvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments); - void (QOPENGLF_APIENTRYP InvalidateBufferData)(GLuint buffer); - void (QOPENGLF_APIENTRYP InvalidateBufferSubData)(GLuint buffer, GLintptr offset, GLsizeiptr length); - void (QOPENGLF_APIENTRYP InvalidateTexImage)(GLuint texture, GLint level); - void (QOPENGLF_APIENTRYP InvalidateTexSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); - void (QOPENGLF_APIENTRYP GetInternalformati64v)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); - void (QOPENGLF_APIENTRYP GetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP FramebufferParameteri)(GLenum target, GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP VertexBindingDivisor)(GLuint bindingindex, GLuint divisor); - void (QOPENGLF_APIENTRYP VertexAttribBinding)(GLuint attribindex, GLuint bindingindex); - void (QOPENGLF_APIENTRYP VertexAttribLFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); - void (QOPENGLF_APIENTRYP VertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); - void (QOPENGLF_APIENTRYP VertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); - void (QOPENGLF_APIENTRYP BindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); - void (QOPENGLF_APIENTRYP TextureView)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); - void (QOPENGLF_APIENTRYP CopyImageSubData)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); - void (QOPENGLF_APIENTRYP DispatchComputeIndirect)(GLintptr indirect); - void (QOPENGLF_APIENTRYP DispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); - void (QOPENGLF_APIENTRYP ClearBufferSubData)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); - void (QOPENGLF_APIENTRYP ClearBufferData)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); - + void(QOPENGLF_APIENTRYP TexStorage3DMultisample)(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations); + void(QOPENGLF_APIENTRYP TexStorage2DMultisample)(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); + void(QOPENGLF_APIENTRYP TexBufferRange)(GLenum target, GLenum internalformat, GLuint buffer, + GLintptr offset, GLsizeiptr size); + void(QOPENGLF_APIENTRYP ShaderStorageBlockBinding)(GLuint program, GLuint storageBlockIndex, + GLuint storageBlockBinding); + GLint(QOPENGLF_APIENTRYP GetProgramResourceLocationIndex)(GLuint program, + GLenum programInterface, + const GLchar *name); + GLint(QOPENGLF_APIENTRYP GetProgramResourceLocation)(GLuint program, GLenum programInterface, + const GLchar *name); + void(QOPENGLF_APIENTRYP GetProgramResourceiv)(GLuint program, GLenum programInterface, + GLuint index, GLsizei propCount, + const GLenum *props, GLsizei bufSize, + GLsizei *length, GLint *params); + void(QOPENGLF_APIENTRYP GetProgramResourceName)(GLuint program, GLenum programInterface, + GLuint index, GLsizei bufSize, GLsizei *length, + GLchar *name); + GLuint(QOPENGLF_APIENTRYP GetProgramResourceIndex)(GLuint program, GLenum programInterface, + const GLchar *name); + void(QOPENGLF_APIENTRYP GetProgramInterfaceiv)(GLuint program, GLenum programInterface, + GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP MultiDrawElementsIndirect)(GLenum mode, GLenum type, + const void *indirect, GLsizei drawcount, + GLsizei stride); + void(QOPENGLF_APIENTRYP MultiDrawArraysIndirect)(GLenum mode, const void *indirect, + GLsizei drawcount, GLsizei stride); + void(QOPENGLF_APIENTRYP InvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, + const GLenum *attachments, GLint x, GLint y, + GLsizei width, GLsizei height); + void(QOPENGLF_APIENTRYP InvalidateFramebuffer)(GLenum target, GLsizei numAttachments, + const GLenum *attachments); + void(QOPENGLF_APIENTRYP InvalidateBufferData)(GLuint buffer); + void(QOPENGLF_APIENTRYP InvalidateBufferSubData)(GLuint buffer, GLintptr offset, + GLsizeiptr length); + void(QOPENGLF_APIENTRYP InvalidateTexImage)(GLuint texture, GLint level); + void(QOPENGLF_APIENTRYP InvalidateTexSubImage)(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth); + void(QOPENGLF_APIENTRYP GetInternalformati64v)(GLenum target, GLenum internalformat, + GLenum pname, GLsizei bufSize, GLint64 *params); + void(QOPENGLF_APIENTRYP GetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP FramebufferParameteri)(GLenum target, GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP VertexBindingDivisor)(GLuint bindingindex, GLuint divisor); + void(QOPENGLF_APIENTRYP VertexAttribBinding)(GLuint attribindex, GLuint bindingindex); + void(QOPENGLF_APIENTRYP VertexAttribLFormat)(GLuint attribindex, GLint size, GLenum type, + GLuint relativeoffset); + void(QOPENGLF_APIENTRYP VertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, + GLuint relativeoffset); + void(QOPENGLF_APIENTRYP VertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, + GLboolean normalized, GLuint relativeoffset); + void(QOPENGLF_APIENTRYP BindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, + GLsizei stride); + void(QOPENGLF_APIENTRYP TextureView)(GLuint texture, GLenum target, GLuint origtexture, + GLenum internalformat, GLuint minlevel, GLuint numlevels, + GLuint minlayer, GLuint numlayers); + void(QOPENGLF_APIENTRYP CopyImageSubData)(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, + GLenum dstTarget, GLint dstLevel, GLint dstX, + GLint dstY, GLint dstZ, GLsizei srcWidth, + GLsizei srcHeight, GLsizei srcDepth); + void(QOPENGLF_APIENTRYP DispatchComputeIndirect)(GLintptr indirect); + void(QOPENGLF_APIENTRYP DispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, + GLuint num_groups_z); + void(QOPENGLF_APIENTRYP ClearBufferSubData)(GLenum target, GLenum internalformat, + GLintptr offset, GLsizeiptr size, GLenum format, + GLenum type, const void *data); + void(QOPENGLF_APIENTRYP ClearBufferData)(GLenum target, GLenum internalformat, GLenum format, + GLenum type, const void *data); }; -class QOpenGLFunctions_1_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_0_DeprecatedBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.0 deprecated functions - void (QOPENGLF_APIENTRYP Translatef)(GLfloat x, GLfloat y, GLfloat z); - void (QOPENGLF_APIENTRYP Translated)(GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP Scalef)(GLfloat x, GLfloat y, GLfloat z); - void (QOPENGLF_APIENTRYP Scaled)(GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP Rotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); - void (QOPENGLF_APIENTRYP Rotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP PushMatrix)(); - void (QOPENGLF_APIENTRYP PopMatrix)(); - void (QOPENGLF_APIENTRYP Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); - void (QOPENGLF_APIENTRYP MultMatrixd)(const GLdouble *m); - void (QOPENGLF_APIENTRYP MultMatrixf)(const GLfloat *m); - void (QOPENGLF_APIENTRYP MatrixMode)(GLenum mode); - void (QOPENGLF_APIENTRYP LoadMatrixd)(const GLdouble *m); - void (QOPENGLF_APIENTRYP LoadMatrixf)(const GLfloat *m); - void (QOPENGLF_APIENTRYP LoadIdentity)(); - void (QOPENGLF_APIENTRYP Frustum)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); - GLboolean (QOPENGLF_APIENTRYP IsList)(GLuint list); - void (QOPENGLF_APIENTRYP GetTexGeniv)(GLenum coord, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetTexGenfv)(GLenum coord, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetTexGendv)(GLenum coord, GLenum pname, GLdouble *params); - void (QOPENGLF_APIENTRYP GetTexEnviv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetTexEnvfv)(GLenum target, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetPolygonStipple)(GLubyte *mask); - void (QOPENGLF_APIENTRYP GetPixelMapusv)(GLenum map, GLushort *values); - void (QOPENGLF_APIENTRYP GetPixelMapuiv)(GLenum map, GLuint *values); - void (QOPENGLF_APIENTRYP GetPixelMapfv)(GLenum map, GLfloat *values); - void (QOPENGLF_APIENTRYP GetMaterialiv)(GLenum face, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetMaterialfv)(GLenum face, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetMapiv)(GLenum target, GLenum query, GLint *v); - void (QOPENGLF_APIENTRYP GetMapfv)(GLenum target, GLenum query, GLfloat *v); - void (QOPENGLF_APIENTRYP GetMapdv)(GLenum target, GLenum query, GLdouble *v); - void (QOPENGLF_APIENTRYP GetLightiv)(GLenum light, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetLightfv)(GLenum light, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetClipPlane)(GLenum plane, GLdouble *equation); - void (QOPENGLF_APIENTRYP DrawPixels)(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); - void (QOPENGLF_APIENTRYP CopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); - void (QOPENGLF_APIENTRYP PixelMapusv)(GLenum map, GLint mapsize, const GLushort *values); - void (QOPENGLF_APIENTRYP PixelMapuiv)(GLenum map, GLint mapsize, const GLuint *values); - void (QOPENGLF_APIENTRYP PixelMapfv)(GLenum map, GLint mapsize, const GLfloat *values); - void (QOPENGLF_APIENTRYP PixelTransferi)(GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP PixelTransferf)(GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP PixelZoom)(GLfloat xfactor, GLfloat yfactor); - void (QOPENGLF_APIENTRYP AlphaFunc)(GLenum func, GLfloat ref); - void (QOPENGLF_APIENTRYP EvalPoint2)(GLint i, GLint j); - void (QOPENGLF_APIENTRYP EvalMesh2)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); - void (QOPENGLF_APIENTRYP EvalPoint1)(GLint i); - void (QOPENGLF_APIENTRYP EvalMesh1)(GLenum mode, GLint i1, GLint i2); - void (QOPENGLF_APIENTRYP EvalCoord2fv)(const GLfloat *u); - void (QOPENGLF_APIENTRYP EvalCoord2f)(GLfloat u, GLfloat v); - void (QOPENGLF_APIENTRYP EvalCoord2dv)(const GLdouble *u); - void (QOPENGLF_APIENTRYP EvalCoord2d)(GLdouble u, GLdouble v); - void (QOPENGLF_APIENTRYP EvalCoord1fv)(const GLfloat *u); - void (QOPENGLF_APIENTRYP EvalCoord1f)(GLfloat u); - void (QOPENGLF_APIENTRYP EvalCoord1dv)(const GLdouble *u); - void (QOPENGLF_APIENTRYP EvalCoord1d)(GLdouble u); - void (QOPENGLF_APIENTRYP MapGrid2f)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); - void (QOPENGLF_APIENTRYP MapGrid2d)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); - void (QOPENGLF_APIENTRYP MapGrid1f)(GLint un, GLfloat u1, GLfloat u2); - void (QOPENGLF_APIENTRYP MapGrid1d)(GLint un, GLdouble u1, GLdouble u2); - void (QOPENGLF_APIENTRYP Map2f)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); - void (QOPENGLF_APIENTRYP Map2d)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); - void (QOPENGLF_APIENTRYP Map1f)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); - void (QOPENGLF_APIENTRYP Map1d)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); - void (QOPENGLF_APIENTRYP PushAttrib)(GLbitfield mask); - void (QOPENGLF_APIENTRYP PopAttrib)(); - void (QOPENGLF_APIENTRYP Accum)(GLenum op, GLfloat value); - void (QOPENGLF_APIENTRYP IndexMask)(GLuint mask); - void (QOPENGLF_APIENTRYP ClearIndex)(GLfloat c); - void (QOPENGLF_APIENTRYP ClearAccum)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - void (QOPENGLF_APIENTRYP PushName)(GLuint name); - void (QOPENGLF_APIENTRYP PopName)(); - void (QOPENGLF_APIENTRYP PassThrough)(GLfloat token); - void (QOPENGLF_APIENTRYP LoadName)(GLuint name); - void (QOPENGLF_APIENTRYP InitNames)(); - GLint (QOPENGLF_APIENTRYP RenderMode)(GLenum mode); - void (QOPENGLF_APIENTRYP SelectBuffer)(GLsizei size, GLuint *buffer); - void (QOPENGLF_APIENTRYP FeedbackBuffer)(GLsizei size, GLenum type, GLfloat *buffer); - void (QOPENGLF_APIENTRYP TexGeniv)(GLenum coord, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP TexGeni)(GLenum coord, GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP TexGenfv)(GLenum coord, GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP TexGenf)(GLenum coord, GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP TexGendv)(GLenum coord, GLenum pname, const GLdouble *params); - void (QOPENGLF_APIENTRYP TexGend)(GLenum coord, GLenum pname, GLdouble param); - void (QOPENGLF_APIENTRYP TexEnviv)(GLenum target, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP TexEnvi)(GLenum target, GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP TexEnvfv)(GLenum target, GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP TexEnvf)(GLenum target, GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP ShadeModel)(GLenum mode); - void (QOPENGLF_APIENTRYP PolygonStipple)(const GLubyte *mask); - void (QOPENGLF_APIENTRYP Materialiv)(GLenum face, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP Materiali)(GLenum face, GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP Materialfv)(GLenum face, GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP Materialf)(GLenum face, GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP LineStipple)(GLint factor, GLushort pattern); - void (QOPENGLF_APIENTRYP LightModeliv)(GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP LightModeli)(GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP LightModelfv)(GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP LightModelf)(GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP Lightiv)(GLenum light, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP Lighti)(GLenum light, GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP Lightfv)(GLenum light, GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP Lightf)(GLenum light, GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP Fogiv)(GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP Fogi)(GLenum pname, GLint param); - void (QOPENGLF_APIENTRYP Fogfv)(GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP Fogf)(GLenum pname, GLfloat param); - void (QOPENGLF_APIENTRYP ColorMaterial)(GLenum face, GLenum mode); - void (QOPENGLF_APIENTRYP ClipPlane)(GLenum plane, const GLdouble *equation); - void (QOPENGLF_APIENTRYP Vertex4sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP Vertex4s)(GLshort x, GLshort y, GLshort z, GLshort w); - void (QOPENGLF_APIENTRYP Vertex4iv)(const GLint *v); - void (QOPENGLF_APIENTRYP Vertex4i)(GLint x, GLint y, GLint z, GLint w); - void (QOPENGLF_APIENTRYP Vertex4fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP Vertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void (QOPENGLF_APIENTRYP Vertex4dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP Vertex4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); - void (QOPENGLF_APIENTRYP Vertex3sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP Vertex3s)(GLshort x, GLshort y, GLshort z); - void (QOPENGLF_APIENTRYP Vertex3iv)(const GLint *v); - void (QOPENGLF_APIENTRYP Vertex3i)(GLint x, GLint y, GLint z); - void (QOPENGLF_APIENTRYP Vertex3fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP Vertex3f)(GLfloat x, GLfloat y, GLfloat z); - void (QOPENGLF_APIENTRYP Vertex3dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP Vertex3d)(GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP Vertex2sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP Vertex2s)(GLshort x, GLshort y); - void (QOPENGLF_APIENTRYP Vertex2iv)(const GLint *v); - void (QOPENGLF_APIENTRYP Vertex2i)(GLint x, GLint y); - void (QOPENGLF_APIENTRYP Vertex2fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP Vertex2f)(GLfloat x, GLfloat y); - void (QOPENGLF_APIENTRYP Vertex2dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP Vertex2d)(GLdouble x, GLdouble y); - void (QOPENGLF_APIENTRYP TexCoord4sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP TexCoord4s)(GLshort s, GLshort t, GLshort r, GLshort q); - void (QOPENGLF_APIENTRYP TexCoord4iv)(const GLint *v); - void (QOPENGLF_APIENTRYP TexCoord4i)(GLint s, GLint t, GLint r, GLint q); - void (QOPENGLF_APIENTRYP TexCoord4fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP TexCoord4f)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); - void (QOPENGLF_APIENTRYP TexCoord4dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP TexCoord4d)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); - void (QOPENGLF_APIENTRYP TexCoord3sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP TexCoord3s)(GLshort s, GLshort t, GLshort r); - void (QOPENGLF_APIENTRYP TexCoord3iv)(const GLint *v); - void (QOPENGLF_APIENTRYP TexCoord3i)(GLint s, GLint t, GLint r); - void (QOPENGLF_APIENTRYP TexCoord3fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP TexCoord3f)(GLfloat s, GLfloat t, GLfloat r); - void (QOPENGLF_APIENTRYP TexCoord3dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP TexCoord3d)(GLdouble s, GLdouble t, GLdouble r); - void (QOPENGLF_APIENTRYP TexCoord2sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP TexCoord2s)(GLshort s, GLshort t); - void (QOPENGLF_APIENTRYP TexCoord2iv)(const GLint *v); - void (QOPENGLF_APIENTRYP TexCoord2i)(GLint s, GLint t); - void (QOPENGLF_APIENTRYP TexCoord2fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP TexCoord2f)(GLfloat s, GLfloat t); - void (QOPENGLF_APIENTRYP TexCoord2dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP TexCoord2d)(GLdouble s, GLdouble t); - void (QOPENGLF_APIENTRYP TexCoord1sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP TexCoord1s)(GLshort s); - void (QOPENGLF_APIENTRYP TexCoord1iv)(const GLint *v); - void (QOPENGLF_APIENTRYP TexCoord1i)(GLint s); - void (QOPENGLF_APIENTRYP TexCoord1fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP TexCoord1f)(GLfloat s); - void (QOPENGLF_APIENTRYP TexCoord1dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP TexCoord1d)(GLdouble s); - void (QOPENGLF_APIENTRYP Rectsv)(const GLshort *v1, const GLshort *v2); - void (QOPENGLF_APIENTRYP Rects)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); - void (QOPENGLF_APIENTRYP Rectiv)(const GLint *v1, const GLint *v2); - void (QOPENGLF_APIENTRYP Recti)(GLint x1, GLint y1, GLint x2, GLint y2); - void (QOPENGLF_APIENTRYP Rectfv)(const GLfloat *v1, const GLfloat *v2); - void (QOPENGLF_APIENTRYP Rectf)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); - void (QOPENGLF_APIENTRYP Rectdv)(const GLdouble *v1, const GLdouble *v2); - void (QOPENGLF_APIENTRYP Rectd)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); - void (QOPENGLF_APIENTRYP RasterPos4sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP RasterPos4s)(GLshort x, GLshort y, GLshort z, GLshort w); - void (QOPENGLF_APIENTRYP RasterPos4iv)(const GLint *v); - void (QOPENGLF_APIENTRYP RasterPos4i)(GLint x, GLint y, GLint z, GLint w); - void (QOPENGLF_APIENTRYP RasterPos4fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP RasterPos4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void (QOPENGLF_APIENTRYP RasterPos4dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP RasterPos4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); - void (QOPENGLF_APIENTRYP RasterPos3sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP RasterPos3s)(GLshort x, GLshort y, GLshort z); - void (QOPENGLF_APIENTRYP RasterPos3iv)(const GLint *v); - void (QOPENGLF_APIENTRYP RasterPos3i)(GLint x, GLint y, GLint z); - void (QOPENGLF_APIENTRYP RasterPos3fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP RasterPos3f)(GLfloat x, GLfloat y, GLfloat z); - void (QOPENGLF_APIENTRYP RasterPos3dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP RasterPos3d)(GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP RasterPos2sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP RasterPos2s)(GLshort x, GLshort y); - void (QOPENGLF_APIENTRYP RasterPos2iv)(const GLint *v); - void (QOPENGLF_APIENTRYP RasterPos2i)(GLint x, GLint y); - void (QOPENGLF_APIENTRYP RasterPos2fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP RasterPos2f)(GLfloat x, GLfloat y); - void (QOPENGLF_APIENTRYP RasterPos2dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP RasterPos2d)(GLdouble x, GLdouble y); - void (QOPENGLF_APIENTRYP Normal3sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP Normal3s)(GLshort nx, GLshort ny, GLshort nz); - void (QOPENGLF_APIENTRYP Normal3iv)(const GLint *v); - void (QOPENGLF_APIENTRYP Normal3i)(GLint nx, GLint ny, GLint nz); - void (QOPENGLF_APIENTRYP Normal3fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP Normal3f)(GLfloat nx, GLfloat ny, GLfloat nz); - void (QOPENGLF_APIENTRYP Normal3dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP Normal3d)(GLdouble nx, GLdouble ny, GLdouble nz); - void (QOPENGLF_APIENTRYP Normal3bv)(const GLbyte *v); - void (QOPENGLF_APIENTRYP Normal3b)(GLbyte nx, GLbyte ny, GLbyte nz); - void (QOPENGLF_APIENTRYP Indexsv)(const GLshort *c); - void (QOPENGLF_APIENTRYP Indexs)(GLshort c); - void (QOPENGLF_APIENTRYP Indexiv)(const GLint *c); - void (QOPENGLF_APIENTRYP Indexi)(GLint c); - void (QOPENGLF_APIENTRYP Indexfv)(const GLfloat *c); - void (QOPENGLF_APIENTRYP Indexf)(GLfloat c); - void (QOPENGLF_APIENTRYP Indexdv)(const GLdouble *c); - void (QOPENGLF_APIENTRYP Indexd)(GLdouble c); - void (QOPENGLF_APIENTRYP End)(); - void (QOPENGLF_APIENTRYP EdgeFlagv)(const GLboolean *flag); - void (QOPENGLF_APIENTRYP EdgeFlag)(GLboolean flag); - void (QOPENGLF_APIENTRYP Color4usv)(const GLushort *v); - void (QOPENGLF_APIENTRYP Color4us)(GLushort red, GLushort green, GLushort blue, GLushort alpha); - void (QOPENGLF_APIENTRYP Color4uiv)(const GLuint *v); - void (QOPENGLF_APIENTRYP Color4ui)(GLuint red, GLuint green, GLuint blue, GLuint alpha); - void (QOPENGLF_APIENTRYP Color4ubv)(const GLubyte *v); - void (QOPENGLF_APIENTRYP Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); - void (QOPENGLF_APIENTRYP Color4sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP Color4s)(GLshort red, GLshort green, GLshort blue, GLshort alpha); - void (QOPENGLF_APIENTRYP Color4iv)(const GLint *v); - void (QOPENGLF_APIENTRYP Color4i)(GLint red, GLint green, GLint blue, GLint alpha); - void (QOPENGLF_APIENTRYP Color4fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP Color4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - void (QOPENGLF_APIENTRYP Color4dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP Color4d)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); - void (QOPENGLF_APIENTRYP Color4bv)(const GLbyte *v); - void (QOPENGLF_APIENTRYP Color4b)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); - void (QOPENGLF_APIENTRYP Color3usv)(const GLushort *v); - void (QOPENGLF_APIENTRYP Color3us)(GLushort red, GLushort green, GLushort blue); - void (QOPENGLF_APIENTRYP Color3uiv)(const GLuint *v); - void (QOPENGLF_APIENTRYP Color3ui)(GLuint red, GLuint green, GLuint blue); - void (QOPENGLF_APIENTRYP Color3ubv)(const GLubyte *v); - void (QOPENGLF_APIENTRYP Color3ub)(GLubyte red, GLubyte green, GLubyte blue); - void (QOPENGLF_APIENTRYP Color3sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP Color3s)(GLshort red, GLshort green, GLshort blue); - void (QOPENGLF_APIENTRYP Color3iv)(const GLint *v); - void (QOPENGLF_APIENTRYP Color3i)(GLint red, GLint green, GLint blue); - void (QOPENGLF_APIENTRYP Color3fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP Color3f)(GLfloat red, GLfloat green, GLfloat blue); - void (QOPENGLF_APIENTRYP Color3dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP Color3d)(GLdouble red, GLdouble green, GLdouble blue); - void (QOPENGLF_APIENTRYP Color3bv)(const GLbyte *v); - void (QOPENGLF_APIENTRYP Color3b)(GLbyte red, GLbyte green, GLbyte blue); - void (QOPENGLF_APIENTRYP Bitmap)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); - void (QOPENGLF_APIENTRYP Begin)(GLenum mode); - void (QOPENGLF_APIENTRYP ListBase)(GLuint base); - GLuint (QOPENGLF_APIENTRYP GenLists)(GLsizei range); - void (QOPENGLF_APIENTRYP DeleteLists)(GLuint list, GLsizei range); - void (QOPENGLF_APIENTRYP CallLists)(GLsizei n, GLenum type, const GLvoid *lists); - void (QOPENGLF_APIENTRYP CallList)(GLuint list); - void (QOPENGLF_APIENTRYP EndList)(); - void (QOPENGLF_APIENTRYP NewList)(GLuint list, GLenum mode); - + void(QOPENGLF_APIENTRYP Translatef)(GLfloat x, GLfloat y, GLfloat z); + void(QOPENGLF_APIENTRYP Translated)(GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP Scalef)(GLfloat x, GLfloat y, GLfloat z); + void(QOPENGLF_APIENTRYP Scaled)(GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP Rotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); + void(QOPENGLF_APIENTRYP Rotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP PushMatrix)(); + void(QOPENGLF_APIENTRYP PopMatrix)(); + void(QOPENGLF_APIENTRYP Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, + GLdouble zNear, GLdouble zFar); + void(QOPENGLF_APIENTRYP MultMatrixd)(const GLdouble *m); + void(QOPENGLF_APIENTRYP MultMatrixf)(const GLfloat *m); + void(QOPENGLF_APIENTRYP MatrixMode)(GLenum mode); + void(QOPENGLF_APIENTRYP LoadMatrixd)(const GLdouble *m); + void(QOPENGLF_APIENTRYP LoadMatrixf)(const GLfloat *m); + void(QOPENGLF_APIENTRYP LoadIdentity)(); + void(QOPENGLF_APIENTRYP Frustum)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, + GLdouble zNear, GLdouble zFar); + GLboolean(QOPENGLF_APIENTRYP IsList)(GLuint list); + void(QOPENGLF_APIENTRYP GetTexGeniv)(GLenum coord, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetTexGenfv)(GLenum coord, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetTexGendv)(GLenum coord, GLenum pname, GLdouble *params); + void(QOPENGLF_APIENTRYP GetTexEnviv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetTexEnvfv)(GLenum target, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetPolygonStipple)(GLubyte *mask); + void(QOPENGLF_APIENTRYP GetPixelMapusv)(GLenum map, GLushort *values); + void(QOPENGLF_APIENTRYP GetPixelMapuiv)(GLenum map, GLuint *values); + void(QOPENGLF_APIENTRYP GetPixelMapfv)(GLenum map, GLfloat *values); + void(QOPENGLF_APIENTRYP GetMaterialiv)(GLenum face, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetMaterialfv)(GLenum face, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetMapiv)(GLenum target, GLenum query, GLint *v); + void(QOPENGLF_APIENTRYP GetMapfv)(GLenum target, GLenum query, GLfloat *v); + void(QOPENGLF_APIENTRYP GetMapdv)(GLenum target, GLenum query, GLdouble *v); + void(QOPENGLF_APIENTRYP GetLightiv)(GLenum light, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetLightfv)(GLenum light, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetClipPlane)(GLenum plane, GLdouble *equation); + void(QOPENGLF_APIENTRYP DrawPixels)(GLsizei width, GLsizei height, GLenum format, GLenum type, + const GLvoid *pixels); + void(QOPENGLF_APIENTRYP CopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum type); + void(QOPENGLF_APIENTRYP PixelMapusv)(GLenum map, GLint mapsize, const GLushort *values); + void(QOPENGLF_APIENTRYP PixelMapuiv)(GLenum map, GLint mapsize, const GLuint *values); + void(QOPENGLF_APIENTRYP PixelMapfv)(GLenum map, GLint mapsize, const GLfloat *values); + void(QOPENGLF_APIENTRYP PixelTransferi)(GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP PixelTransferf)(GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP PixelZoom)(GLfloat xfactor, GLfloat yfactor); + void(QOPENGLF_APIENTRYP AlphaFunc)(GLenum func, GLfloat ref); + void(QOPENGLF_APIENTRYP EvalPoint2)(GLint i, GLint j); + void(QOPENGLF_APIENTRYP EvalMesh2)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); + void(QOPENGLF_APIENTRYP EvalPoint1)(GLint i); + void(QOPENGLF_APIENTRYP EvalMesh1)(GLenum mode, GLint i1, GLint i2); + void(QOPENGLF_APIENTRYP EvalCoord2fv)(const GLfloat *u); + void(QOPENGLF_APIENTRYP EvalCoord2f)(GLfloat u, GLfloat v); + void(QOPENGLF_APIENTRYP EvalCoord2dv)(const GLdouble *u); + void(QOPENGLF_APIENTRYP EvalCoord2d)(GLdouble u, GLdouble v); + void(QOPENGLF_APIENTRYP EvalCoord1fv)(const GLfloat *u); + void(QOPENGLF_APIENTRYP EvalCoord1f)(GLfloat u); + void(QOPENGLF_APIENTRYP EvalCoord1dv)(const GLdouble *u); + void(QOPENGLF_APIENTRYP EvalCoord1d)(GLdouble u); + void(QOPENGLF_APIENTRYP MapGrid2f)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, + GLfloat v2); + void(QOPENGLF_APIENTRYP MapGrid2d)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, + GLdouble v2); + void(QOPENGLF_APIENTRYP MapGrid1f)(GLint un, GLfloat u1, GLfloat u2); + void(QOPENGLF_APIENTRYP MapGrid1d)(GLint un, GLdouble u1, GLdouble u2); + void(QOPENGLF_APIENTRYP Map2f)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, + GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, + GLint vorder, const GLfloat *points); + void(QOPENGLF_APIENTRYP Map2d)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, + GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, + GLint vorder, const GLdouble *points); + void(QOPENGLF_APIENTRYP Map1f)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, + const GLfloat *points); + void(QOPENGLF_APIENTRYP Map1d)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, + GLint order, const GLdouble *points); + void(QOPENGLF_APIENTRYP PushAttrib)(GLbitfield mask); + void(QOPENGLF_APIENTRYP PopAttrib)(); + void(QOPENGLF_APIENTRYP Accum)(GLenum op, GLfloat value); + void(QOPENGLF_APIENTRYP IndexMask)(GLuint mask); + void(QOPENGLF_APIENTRYP ClearIndex)(GLfloat c); + void(QOPENGLF_APIENTRYP ClearAccum)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void(QOPENGLF_APIENTRYP PushName)(GLuint name); + void(QOPENGLF_APIENTRYP PopName)(); + void(QOPENGLF_APIENTRYP PassThrough)(GLfloat token); + void(QOPENGLF_APIENTRYP LoadName)(GLuint name); + void(QOPENGLF_APIENTRYP InitNames)(); + GLint(QOPENGLF_APIENTRYP RenderMode)(GLenum mode); + void(QOPENGLF_APIENTRYP SelectBuffer)(GLsizei size, GLuint *buffer); + void(QOPENGLF_APIENTRYP FeedbackBuffer)(GLsizei size, GLenum type, GLfloat *buffer); + void(QOPENGLF_APIENTRYP TexGeniv)(GLenum coord, GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP TexGeni)(GLenum coord, GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP TexGenfv)(GLenum coord, GLenum pname, const GLfloat *params); + void(QOPENGLF_APIENTRYP TexGenf)(GLenum coord, GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP TexGendv)(GLenum coord, GLenum pname, const GLdouble *params); + void(QOPENGLF_APIENTRYP TexGend)(GLenum coord, GLenum pname, GLdouble param); + void(QOPENGLF_APIENTRYP TexEnviv)(GLenum target, GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP TexEnvi)(GLenum target, GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP TexEnvfv)(GLenum target, GLenum pname, const GLfloat *params); + void(QOPENGLF_APIENTRYP TexEnvf)(GLenum target, GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP ShadeModel)(GLenum mode); + void(QOPENGLF_APIENTRYP PolygonStipple)(const GLubyte *mask); + void(QOPENGLF_APIENTRYP Materialiv)(GLenum face, GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP Materiali)(GLenum face, GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP Materialfv)(GLenum face, GLenum pname, const GLfloat *params); + void(QOPENGLF_APIENTRYP Materialf)(GLenum face, GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP LineStipple)(GLint factor, GLushort pattern); + void(QOPENGLF_APIENTRYP LightModeliv)(GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP LightModeli)(GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP LightModelfv)(GLenum pname, const GLfloat *params); + void(QOPENGLF_APIENTRYP LightModelf)(GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP Lightiv)(GLenum light, GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP Lighti)(GLenum light, GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP Lightfv)(GLenum light, GLenum pname, const GLfloat *params); + void(QOPENGLF_APIENTRYP Lightf)(GLenum light, GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP Fogiv)(GLenum pname, const GLint *params); + void(QOPENGLF_APIENTRYP Fogi)(GLenum pname, GLint param); + void(QOPENGLF_APIENTRYP Fogfv)(GLenum pname, const GLfloat *params); + void(QOPENGLF_APIENTRYP Fogf)(GLenum pname, GLfloat param); + void(QOPENGLF_APIENTRYP ColorMaterial)(GLenum face, GLenum mode); + void(QOPENGLF_APIENTRYP ClipPlane)(GLenum plane, const GLdouble *equation); + void(QOPENGLF_APIENTRYP Vertex4sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP Vertex4s)(GLshort x, GLshort y, GLshort z, GLshort w); + void(QOPENGLF_APIENTRYP Vertex4iv)(const GLint *v); + void(QOPENGLF_APIENTRYP Vertex4i)(GLint x, GLint y, GLint z, GLint w); + void(QOPENGLF_APIENTRYP Vertex4fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP Vertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void(QOPENGLF_APIENTRYP Vertex4dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP Vertex4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + void(QOPENGLF_APIENTRYP Vertex3sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP Vertex3s)(GLshort x, GLshort y, GLshort z); + void(QOPENGLF_APIENTRYP Vertex3iv)(const GLint *v); + void(QOPENGLF_APIENTRYP Vertex3i)(GLint x, GLint y, GLint z); + void(QOPENGLF_APIENTRYP Vertex3fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP Vertex3f)(GLfloat x, GLfloat y, GLfloat z); + void(QOPENGLF_APIENTRYP Vertex3dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP Vertex3d)(GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP Vertex2sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP Vertex2s)(GLshort x, GLshort y); + void(QOPENGLF_APIENTRYP Vertex2iv)(const GLint *v); + void(QOPENGLF_APIENTRYP Vertex2i)(GLint x, GLint y); + void(QOPENGLF_APIENTRYP Vertex2fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP Vertex2f)(GLfloat x, GLfloat y); + void(QOPENGLF_APIENTRYP Vertex2dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP Vertex2d)(GLdouble x, GLdouble y); + void(QOPENGLF_APIENTRYP TexCoord4sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP TexCoord4s)(GLshort s, GLshort t, GLshort r, GLshort q); + void(QOPENGLF_APIENTRYP TexCoord4iv)(const GLint *v); + void(QOPENGLF_APIENTRYP TexCoord4i)(GLint s, GLint t, GLint r, GLint q); + void(QOPENGLF_APIENTRYP TexCoord4fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP TexCoord4f)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); + void(QOPENGLF_APIENTRYP TexCoord4dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP TexCoord4d)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); + void(QOPENGLF_APIENTRYP TexCoord3sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP TexCoord3s)(GLshort s, GLshort t, GLshort r); + void(QOPENGLF_APIENTRYP TexCoord3iv)(const GLint *v); + void(QOPENGLF_APIENTRYP TexCoord3i)(GLint s, GLint t, GLint r); + void(QOPENGLF_APIENTRYP TexCoord3fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP TexCoord3f)(GLfloat s, GLfloat t, GLfloat r); + void(QOPENGLF_APIENTRYP TexCoord3dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP TexCoord3d)(GLdouble s, GLdouble t, GLdouble r); + void(QOPENGLF_APIENTRYP TexCoord2sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP TexCoord2s)(GLshort s, GLshort t); + void(QOPENGLF_APIENTRYP TexCoord2iv)(const GLint *v); + void(QOPENGLF_APIENTRYP TexCoord2i)(GLint s, GLint t); + void(QOPENGLF_APIENTRYP TexCoord2fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP TexCoord2f)(GLfloat s, GLfloat t); + void(QOPENGLF_APIENTRYP TexCoord2dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP TexCoord2d)(GLdouble s, GLdouble t); + void(QOPENGLF_APIENTRYP TexCoord1sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP TexCoord1s)(GLshort s); + void(QOPENGLF_APIENTRYP TexCoord1iv)(const GLint *v); + void(QOPENGLF_APIENTRYP TexCoord1i)(GLint s); + void(QOPENGLF_APIENTRYP TexCoord1fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP TexCoord1f)(GLfloat s); + void(QOPENGLF_APIENTRYP TexCoord1dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP TexCoord1d)(GLdouble s); + void(QOPENGLF_APIENTRYP Rectsv)(const GLshort *v1, const GLshort *v2); + void(QOPENGLF_APIENTRYP Rects)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); + void(QOPENGLF_APIENTRYP Rectiv)(const GLint *v1, const GLint *v2); + void(QOPENGLF_APIENTRYP Recti)(GLint x1, GLint y1, GLint x2, GLint y2); + void(QOPENGLF_APIENTRYP Rectfv)(const GLfloat *v1, const GLfloat *v2); + void(QOPENGLF_APIENTRYP Rectf)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); + void(QOPENGLF_APIENTRYP Rectdv)(const GLdouble *v1, const GLdouble *v2); + void(QOPENGLF_APIENTRYP Rectd)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); + void(QOPENGLF_APIENTRYP RasterPos4sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP RasterPos4s)(GLshort x, GLshort y, GLshort z, GLshort w); + void(QOPENGLF_APIENTRYP RasterPos4iv)(const GLint *v); + void(QOPENGLF_APIENTRYP RasterPos4i)(GLint x, GLint y, GLint z, GLint w); + void(QOPENGLF_APIENTRYP RasterPos4fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP RasterPos4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void(QOPENGLF_APIENTRYP RasterPos4dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP RasterPos4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + void(QOPENGLF_APIENTRYP RasterPos3sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP RasterPos3s)(GLshort x, GLshort y, GLshort z); + void(QOPENGLF_APIENTRYP RasterPos3iv)(const GLint *v); + void(QOPENGLF_APIENTRYP RasterPos3i)(GLint x, GLint y, GLint z); + void(QOPENGLF_APIENTRYP RasterPos3fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP RasterPos3f)(GLfloat x, GLfloat y, GLfloat z); + void(QOPENGLF_APIENTRYP RasterPos3dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP RasterPos3d)(GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP RasterPos2sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP RasterPos2s)(GLshort x, GLshort y); + void(QOPENGLF_APIENTRYP RasterPos2iv)(const GLint *v); + void(QOPENGLF_APIENTRYP RasterPos2i)(GLint x, GLint y); + void(QOPENGLF_APIENTRYP RasterPos2fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP RasterPos2f)(GLfloat x, GLfloat y); + void(QOPENGLF_APIENTRYP RasterPos2dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP RasterPos2d)(GLdouble x, GLdouble y); + void(QOPENGLF_APIENTRYP Normal3sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP Normal3s)(GLshort nx, GLshort ny, GLshort nz); + void(QOPENGLF_APIENTRYP Normal3iv)(const GLint *v); + void(QOPENGLF_APIENTRYP Normal3i)(GLint nx, GLint ny, GLint nz); + void(QOPENGLF_APIENTRYP Normal3fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP Normal3f)(GLfloat nx, GLfloat ny, GLfloat nz); + void(QOPENGLF_APIENTRYP Normal3dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP Normal3d)(GLdouble nx, GLdouble ny, GLdouble nz); + void(QOPENGLF_APIENTRYP Normal3bv)(const GLbyte *v); + void(QOPENGLF_APIENTRYP Normal3b)(GLbyte nx, GLbyte ny, GLbyte nz); + void(QOPENGLF_APIENTRYP Indexsv)(const GLshort *c); + void(QOPENGLF_APIENTRYP Indexs)(GLshort c); + void(QOPENGLF_APIENTRYP Indexiv)(const GLint *c); + void(QOPENGLF_APIENTRYP Indexi)(GLint c); + void(QOPENGLF_APIENTRYP Indexfv)(const GLfloat *c); + void(QOPENGLF_APIENTRYP Indexf)(GLfloat c); + void(QOPENGLF_APIENTRYP Indexdv)(const GLdouble *c); + void(QOPENGLF_APIENTRYP Indexd)(GLdouble c); + void(QOPENGLF_APIENTRYP End)(); + void(QOPENGLF_APIENTRYP EdgeFlagv)(const GLboolean *flag); + void(QOPENGLF_APIENTRYP EdgeFlag)(GLboolean flag); + void(QOPENGLF_APIENTRYP Color4usv)(const GLushort *v); + void(QOPENGLF_APIENTRYP Color4us)(GLushort red, GLushort green, GLushort blue, GLushort alpha); + void(QOPENGLF_APIENTRYP Color4uiv)(const GLuint *v); + void(QOPENGLF_APIENTRYP Color4ui)(GLuint red, GLuint green, GLuint blue, GLuint alpha); + void(QOPENGLF_APIENTRYP Color4ubv)(const GLubyte *v); + void(QOPENGLF_APIENTRYP Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); + void(QOPENGLF_APIENTRYP Color4sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP Color4s)(GLshort red, GLshort green, GLshort blue, GLshort alpha); + void(QOPENGLF_APIENTRYP Color4iv)(const GLint *v); + void(QOPENGLF_APIENTRYP Color4i)(GLint red, GLint green, GLint blue, GLint alpha); + void(QOPENGLF_APIENTRYP Color4fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP Color4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void(QOPENGLF_APIENTRYP Color4dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP Color4d)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); + void(QOPENGLF_APIENTRYP Color4bv)(const GLbyte *v); + void(QOPENGLF_APIENTRYP Color4b)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); + void(QOPENGLF_APIENTRYP Color3usv)(const GLushort *v); + void(QOPENGLF_APIENTRYP Color3us)(GLushort red, GLushort green, GLushort blue); + void(QOPENGLF_APIENTRYP Color3uiv)(const GLuint *v); + void(QOPENGLF_APIENTRYP Color3ui)(GLuint red, GLuint green, GLuint blue); + void(QOPENGLF_APIENTRYP Color3ubv)(const GLubyte *v); + void(QOPENGLF_APIENTRYP Color3ub)(GLubyte red, GLubyte green, GLubyte blue); + void(QOPENGLF_APIENTRYP Color3sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP Color3s)(GLshort red, GLshort green, GLshort blue); + void(QOPENGLF_APIENTRYP Color3iv)(const GLint *v); + void(QOPENGLF_APIENTRYP Color3i)(GLint red, GLint green, GLint blue); + void(QOPENGLF_APIENTRYP Color3fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP Color3f)(GLfloat red, GLfloat green, GLfloat blue); + void(QOPENGLF_APIENTRYP Color3dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP Color3d)(GLdouble red, GLdouble green, GLdouble blue); + void(QOPENGLF_APIENTRYP Color3bv)(const GLbyte *v); + void(QOPENGLF_APIENTRYP Color3b)(GLbyte red, GLbyte green, GLbyte blue); + void(QOPENGLF_APIENTRYP Bitmap)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); + void(QOPENGLF_APIENTRYP Begin)(GLenum mode); + void(QOPENGLF_APIENTRYP ListBase)(GLuint base); + GLuint(QOPENGLF_APIENTRYP GenLists)(GLsizei range); + void(QOPENGLF_APIENTRYP DeleteLists)(GLuint list, GLsizei range); + void(QOPENGLF_APIENTRYP CallLists)(GLsizei n, GLenum type, const GLvoid *lists); + void(QOPENGLF_APIENTRYP CallList)(GLuint list); + void(QOPENGLF_APIENTRYP EndList)(); + void(QOPENGLF_APIENTRYP NewList)(GLuint list, GLenum mode); }; -class QOpenGLFunctions_1_1_DeprecatedBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_1_DeprecatedBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_1_DeprecatedBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.1 deprecated functions - void (QOPENGLF_APIENTRYP PushClientAttrib)(GLbitfield mask); - void (QOPENGLF_APIENTRYP PopClientAttrib)(); - void (QOPENGLF_APIENTRYP PrioritizeTextures)(GLsizei n, const GLuint *textures, const GLfloat *priorities); - GLboolean (QOPENGLF_APIENTRYP AreTexturesResident)(GLsizei n, const GLuint *textures, GLboolean *residences); - void (QOPENGLF_APIENTRYP VertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP TexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP NormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP InterleavedArrays)(GLenum format, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP IndexPointer)(GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP EnableClientState)(GLenum array); - void (QOPENGLF_APIENTRYP EdgeFlagPointer)(GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP DisableClientState)(GLenum array); - void (QOPENGLF_APIENTRYP ColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP ArrayElement)(GLint i); - + void(QOPENGLF_APIENTRYP PushClientAttrib)(GLbitfield mask); + void(QOPENGLF_APIENTRYP PopClientAttrib)(); + void(QOPENGLF_APIENTRYP PrioritizeTextures)(GLsizei n, const GLuint *textures, + const GLfloat *priorities); + GLboolean(QOPENGLF_APIENTRYP AreTexturesResident)(GLsizei n, const GLuint *textures, + GLboolean *residences); + void(QOPENGLF_APIENTRYP VertexPointer)(GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer); + void(QOPENGLF_APIENTRYP TexCoordPointer)(GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer); + void(QOPENGLF_APIENTRYP NormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer); + void(QOPENGLF_APIENTRYP InterleavedArrays)(GLenum format, GLsizei stride, + const GLvoid *pointer); + void(QOPENGLF_APIENTRYP IndexPointer)(GLenum type, GLsizei stride, const GLvoid *pointer); + void(QOPENGLF_APIENTRYP EnableClientState)(GLenum array); + void(QOPENGLF_APIENTRYP EdgeFlagPointer)(GLsizei stride, const GLvoid *pointer); + void(QOPENGLF_APIENTRYP DisableClientState)(GLenum array); + void(QOPENGLF_APIENTRYP ColorPointer)(GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer); + void(QOPENGLF_APIENTRYP ArrayElement)(GLint i); }; -class QOpenGLFunctions_1_2_DeprecatedBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_2_DeprecatedBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_2_DeprecatedBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.2 deprecated functions - void (QOPENGLF_APIENTRYP ResetMinmax)(GLenum target); - void (QOPENGLF_APIENTRYP ResetHistogram)(GLenum target); - void (QOPENGLF_APIENTRYP Minmax)(GLenum target, GLenum internalformat, GLboolean sink); - void (QOPENGLF_APIENTRYP Histogram)(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); - void (QOPENGLF_APIENTRYP GetMinmaxParameteriv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetMinmaxParameterfv)(GLenum target, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetMinmax)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); - void (QOPENGLF_APIENTRYP GetHistogramParameteriv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetHistogramParameterfv)(GLenum target, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetHistogram)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); - void (QOPENGLF_APIENTRYP SeparableFilter2D)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); - void (QOPENGLF_APIENTRYP GetSeparableFilter)(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); - void (QOPENGLF_APIENTRYP GetConvolutionParameteriv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetConvolutionParameterfv)(GLenum target, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetConvolutionFilter)(GLenum target, GLenum format, GLenum type, GLvoid *image); - void (QOPENGLF_APIENTRYP CopyConvolutionFilter2D)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); - void (QOPENGLF_APIENTRYP CopyConvolutionFilter1D)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); - void (QOPENGLF_APIENTRYP ConvolutionParameteriv)(GLenum target, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP ConvolutionParameteri)(GLenum target, GLenum pname, GLint params); - void (QOPENGLF_APIENTRYP ConvolutionParameterfv)(GLenum target, GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP ConvolutionParameterf)(GLenum target, GLenum pname, GLfloat params); - void (QOPENGLF_APIENTRYP ConvolutionFilter2D)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); - void (QOPENGLF_APIENTRYP ConvolutionFilter1D)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); - void (QOPENGLF_APIENTRYP CopyColorSubTable)(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); - void (QOPENGLF_APIENTRYP ColorSubTable)(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); - void (QOPENGLF_APIENTRYP GetColorTableParameteriv)(GLenum target, GLenum pname, GLint *params); - void (QOPENGLF_APIENTRYP GetColorTableParameterfv)(GLenum target, GLenum pname, GLfloat *params); - void (QOPENGLF_APIENTRYP GetColorTable)(GLenum target, GLenum format, GLenum type, GLvoid *table); - void (QOPENGLF_APIENTRYP CopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); - void (QOPENGLF_APIENTRYP ColorTableParameteriv)(GLenum target, GLenum pname, const GLint *params); - void (QOPENGLF_APIENTRYP ColorTableParameterfv)(GLenum target, GLenum pname, const GLfloat *params); - void (QOPENGLF_APIENTRYP ColorTable)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); - + void(QOPENGLF_APIENTRYP ResetMinmax)(GLenum target); + void(QOPENGLF_APIENTRYP ResetHistogram)(GLenum target); + void(QOPENGLF_APIENTRYP Minmax)(GLenum target, GLenum internalformat, GLboolean sink); + void(QOPENGLF_APIENTRYP Histogram)(GLenum target, GLsizei width, GLenum internalformat, + GLboolean sink); + void(QOPENGLF_APIENTRYP GetMinmaxParameteriv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetMinmaxParameterfv)(GLenum target, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetMinmax)(GLenum target, GLboolean reset, GLenum format, GLenum type, + GLvoid *values); + void(QOPENGLF_APIENTRYP GetHistogramParameteriv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetHistogramParameterfv)(GLenum target, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetHistogram)(GLenum target, GLboolean reset, GLenum format, + GLenum type, GLvoid *values); + void(QOPENGLF_APIENTRYP SeparableFilter2D)(GLenum target, GLenum internalformat, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const GLvoid *row, const GLvoid *column); + void(QOPENGLF_APIENTRYP GetSeparableFilter)(GLenum target, GLenum format, GLenum type, + GLvoid *row, GLvoid *column, GLvoid *span); + void(QOPENGLF_APIENTRYP GetConvolutionParameteriv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetConvolutionParameterfv)(GLenum target, GLenum pname, + GLfloat *params); + void(QOPENGLF_APIENTRYP GetConvolutionFilter)(GLenum target, GLenum format, GLenum type, + GLvoid *image); + void(QOPENGLF_APIENTRYP CopyConvolutionFilter2D)(GLenum target, GLenum internalformat, GLint x, + GLint y, GLsizei width, GLsizei height); + void(QOPENGLF_APIENTRYP CopyConvolutionFilter1D)(GLenum target, GLenum internalformat, GLint x, + GLint y, GLsizei width); + void(QOPENGLF_APIENTRYP ConvolutionParameteriv)(GLenum target, GLenum pname, + const GLint *params); + void(QOPENGLF_APIENTRYP ConvolutionParameteri)(GLenum target, GLenum pname, GLint params); + void(QOPENGLF_APIENTRYP ConvolutionParameterfv)(GLenum target, GLenum pname, + const GLfloat *params); + void(QOPENGLF_APIENTRYP ConvolutionParameterf)(GLenum target, GLenum pname, GLfloat params); + void(QOPENGLF_APIENTRYP ConvolutionFilter2D)(GLenum target, GLenum internalformat, + GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *image); + void(QOPENGLF_APIENTRYP ConvolutionFilter1D)(GLenum target, GLenum internalformat, + GLsizei width, GLenum format, GLenum type, + const GLvoid *image); + void(QOPENGLF_APIENTRYP CopyColorSubTable)(GLenum target, GLsizei start, GLint x, GLint y, + GLsizei width); + void(QOPENGLF_APIENTRYP ColorSubTable)(GLenum target, GLsizei start, GLsizei count, + GLenum format, GLenum type, const GLvoid *data); + void(QOPENGLF_APIENTRYP GetColorTableParameteriv)(GLenum target, GLenum pname, GLint *params); + void(QOPENGLF_APIENTRYP GetColorTableParameterfv)(GLenum target, GLenum pname, GLfloat *params); + void(QOPENGLF_APIENTRYP GetColorTable)(GLenum target, GLenum format, GLenum type, + GLvoid *table); + void(QOPENGLF_APIENTRYP CopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, + GLsizei width); + void(QOPENGLF_APIENTRYP ColorTableParameteriv)(GLenum target, GLenum pname, + const GLint *params); + void(QOPENGLF_APIENTRYP ColorTableParameterfv)(GLenum target, GLenum pname, + const GLfloat *params); + void(QOPENGLF_APIENTRYP ColorTable)(GLenum target, GLenum internalformat, GLsizei width, + GLenum format, GLenum type, const GLvoid *table); }; -class QOpenGLFunctions_1_3_DeprecatedBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_3_DeprecatedBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_3_DeprecatedBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.3 deprecated functions - void (QOPENGLF_APIENTRYP MultTransposeMatrixd)(const GLdouble *m); - void (QOPENGLF_APIENTRYP MultTransposeMatrixf)(const GLfloat *m); - void (QOPENGLF_APIENTRYP LoadTransposeMatrixd)(const GLdouble *m); - void (QOPENGLF_APIENTRYP LoadTransposeMatrixf)(const GLfloat *m); - void (QOPENGLF_APIENTRYP MultiTexCoord4sv)(GLenum target, const GLshort *v); - void (QOPENGLF_APIENTRYP MultiTexCoord4s)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); - void (QOPENGLF_APIENTRYP MultiTexCoord4iv)(GLenum target, const GLint *v); - void (QOPENGLF_APIENTRYP MultiTexCoord4i)(GLenum target, GLint s, GLint t, GLint r, GLint q); - void (QOPENGLF_APIENTRYP MultiTexCoord4fv)(GLenum target, const GLfloat *v); - void (QOPENGLF_APIENTRYP MultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); - void (QOPENGLF_APIENTRYP MultiTexCoord4dv)(GLenum target, const GLdouble *v); - void (QOPENGLF_APIENTRYP MultiTexCoord4d)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); - void (QOPENGLF_APIENTRYP MultiTexCoord3sv)(GLenum target, const GLshort *v); - void (QOPENGLF_APIENTRYP MultiTexCoord3s)(GLenum target, GLshort s, GLshort t, GLshort r); - void (QOPENGLF_APIENTRYP MultiTexCoord3iv)(GLenum target, const GLint *v); - void (QOPENGLF_APIENTRYP MultiTexCoord3i)(GLenum target, GLint s, GLint t, GLint r); - void (QOPENGLF_APIENTRYP MultiTexCoord3fv)(GLenum target, const GLfloat *v); - void (QOPENGLF_APIENTRYP MultiTexCoord3f)(GLenum target, GLfloat s, GLfloat t, GLfloat r); - void (QOPENGLF_APIENTRYP MultiTexCoord3dv)(GLenum target, const GLdouble *v); - void (QOPENGLF_APIENTRYP MultiTexCoord3d)(GLenum target, GLdouble s, GLdouble t, GLdouble r); - void (QOPENGLF_APIENTRYP MultiTexCoord2sv)(GLenum target, const GLshort *v); - void (QOPENGLF_APIENTRYP MultiTexCoord2s)(GLenum target, GLshort s, GLshort t); - void (QOPENGLF_APIENTRYP MultiTexCoord2iv)(GLenum target, const GLint *v); - void (QOPENGLF_APIENTRYP MultiTexCoord2i)(GLenum target, GLint s, GLint t); - void (QOPENGLF_APIENTRYP MultiTexCoord2fv)(GLenum target, const GLfloat *v); - void (QOPENGLF_APIENTRYP MultiTexCoord2f)(GLenum target, GLfloat s, GLfloat t); - void (QOPENGLF_APIENTRYP MultiTexCoord2dv)(GLenum target, const GLdouble *v); - void (QOPENGLF_APIENTRYP MultiTexCoord2d)(GLenum target, GLdouble s, GLdouble t); - void (QOPENGLF_APIENTRYP MultiTexCoord1sv)(GLenum target, const GLshort *v); - void (QOPENGLF_APIENTRYP MultiTexCoord1s)(GLenum target, GLshort s); - void (QOPENGLF_APIENTRYP MultiTexCoord1iv)(GLenum target, const GLint *v); - void (QOPENGLF_APIENTRYP MultiTexCoord1i)(GLenum target, GLint s); - void (QOPENGLF_APIENTRYP MultiTexCoord1fv)(GLenum target, const GLfloat *v); - void (QOPENGLF_APIENTRYP MultiTexCoord1f)(GLenum target, GLfloat s); - void (QOPENGLF_APIENTRYP MultiTexCoord1dv)(GLenum target, const GLdouble *v); - void (QOPENGLF_APIENTRYP MultiTexCoord1d)(GLenum target, GLdouble s); - void (QOPENGLF_APIENTRYP ClientActiveTexture)(GLenum texture); - + void(QOPENGLF_APIENTRYP MultTransposeMatrixd)(const GLdouble *m); + void(QOPENGLF_APIENTRYP MultTransposeMatrixf)(const GLfloat *m); + void(QOPENGLF_APIENTRYP LoadTransposeMatrixd)(const GLdouble *m); + void(QOPENGLF_APIENTRYP LoadTransposeMatrixf)(const GLfloat *m); + void(QOPENGLF_APIENTRYP MultiTexCoord4sv)(GLenum target, const GLshort *v); + void(QOPENGLF_APIENTRYP MultiTexCoord4s)(GLenum target, GLshort s, GLshort t, GLshort r, + GLshort q); + void(QOPENGLF_APIENTRYP MultiTexCoord4iv)(GLenum target, const GLint *v); + void(QOPENGLF_APIENTRYP MultiTexCoord4i)(GLenum target, GLint s, GLint t, GLint r, GLint q); + void(QOPENGLF_APIENTRYP MultiTexCoord4fv)(GLenum target, const GLfloat *v); + void(QOPENGLF_APIENTRYP MultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, + GLfloat q); + void(QOPENGLF_APIENTRYP MultiTexCoord4dv)(GLenum target, const GLdouble *v); + void(QOPENGLF_APIENTRYP MultiTexCoord4d)(GLenum target, GLdouble s, GLdouble t, GLdouble r, + GLdouble q); + void(QOPENGLF_APIENTRYP MultiTexCoord3sv)(GLenum target, const GLshort *v); + void(QOPENGLF_APIENTRYP MultiTexCoord3s)(GLenum target, GLshort s, GLshort t, GLshort r); + void(QOPENGLF_APIENTRYP MultiTexCoord3iv)(GLenum target, const GLint *v); + void(QOPENGLF_APIENTRYP MultiTexCoord3i)(GLenum target, GLint s, GLint t, GLint r); + void(QOPENGLF_APIENTRYP MultiTexCoord3fv)(GLenum target, const GLfloat *v); + void(QOPENGLF_APIENTRYP MultiTexCoord3f)(GLenum target, GLfloat s, GLfloat t, GLfloat r); + void(QOPENGLF_APIENTRYP MultiTexCoord3dv)(GLenum target, const GLdouble *v); + void(QOPENGLF_APIENTRYP MultiTexCoord3d)(GLenum target, GLdouble s, GLdouble t, GLdouble r); + void(QOPENGLF_APIENTRYP MultiTexCoord2sv)(GLenum target, const GLshort *v); + void(QOPENGLF_APIENTRYP MultiTexCoord2s)(GLenum target, GLshort s, GLshort t); + void(QOPENGLF_APIENTRYP MultiTexCoord2iv)(GLenum target, const GLint *v); + void(QOPENGLF_APIENTRYP MultiTexCoord2i)(GLenum target, GLint s, GLint t); + void(QOPENGLF_APIENTRYP MultiTexCoord2fv)(GLenum target, const GLfloat *v); + void(QOPENGLF_APIENTRYP MultiTexCoord2f)(GLenum target, GLfloat s, GLfloat t); + void(QOPENGLF_APIENTRYP MultiTexCoord2dv)(GLenum target, const GLdouble *v); + void(QOPENGLF_APIENTRYP MultiTexCoord2d)(GLenum target, GLdouble s, GLdouble t); + void(QOPENGLF_APIENTRYP MultiTexCoord1sv)(GLenum target, const GLshort *v); + void(QOPENGLF_APIENTRYP MultiTexCoord1s)(GLenum target, GLshort s); + void(QOPENGLF_APIENTRYP MultiTexCoord1iv)(GLenum target, const GLint *v); + void(QOPENGLF_APIENTRYP MultiTexCoord1i)(GLenum target, GLint s); + void(QOPENGLF_APIENTRYP MultiTexCoord1fv)(GLenum target, const GLfloat *v); + void(QOPENGLF_APIENTRYP MultiTexCoord1f)(GLenum target, GLfloat s); + void(QOPENGLF_APIENTRYP MultiTexCoord1dv)(GLenum target, const GLdouble *v); + void(QOPENGLF_APIENTRYP MultiTexCoord1d)(GLenum target, GLdouble s); + void(QOPENGLF_APIENTRYP ClientActiveTexture)(GLenum texture); }; -class QOpenGLFunctions_1_4_DeprecatedBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_1_4_DeprecatedBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_1_4_DeprecatedBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 1.4 deprecated functions - void (QOPENGLF_APIENTRYP WindowPos3sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP WindowPos3s)(GLshort x, GLshort y, GLshort z); - void (QOPENGLF_APIENTRYP WindowPos3iv)(const GLint *v); - void (QOPENGLF_APIENTRYP WindowPos3i)(GLint x, GLint y, GLint z); - void (QOPENGLF_APIENTRYP WindowPos3fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP WindowPos3f)(GLfloat x, GLfloat y, GLfloat z); - void (QOPENGLF_APIENTRYP WindowPos3dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP WindowPos3d)(GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP WindowPos2sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP WindowPos2s)(GLshort x, GLshort y); - void (QOPENGLF_APIENTRYP WindowPos2iv)(const GLint *v); - void (QOPENGLF_APIENTRYP WindowPos2i)(GLint x, GLint y); - void (QOPENGLF_APIENTRYP WindowPos2fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP WindowPos2f)(GLfloat x, GLfloat y); - void (QOPENGLF_APIENTRYP WindowPos2dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP WindowPos2d)(GLdouble x, GLdouble y); - void (QOPENGLF_APIENTRYP SecondaryColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP SecondaryColor3usv)(const GLushort *v); - void (QOPENGLF_APIENTRYP SecondaryColor3us)(GLushort red, GLushort green, GLushort blue); - void (QOPENGLF_APIENTRYP SecondaryColor3uiv)(const GLuint *v); - void (QOPENGLF_APIENTRYP SecondaryColor3ui)(GLuint red, GLuint green, GLuint blue); - void (QOPENGLF_APIENTRYP SecondaryColor3ubv)(const GLubyte *v); - void (QOPENGLF_APIENTRYP SecondaryColor3ub)(GLubyte red, GLubyte green, GLubyte blue); - void (QOPENGLF_APIENTRYP SecondaryColor3sv)(const GLshort *v); - void (QOPENGLF_APIENTRYP SecondaryColor3s)(GLshort red, GLshort green, GLshort blue); - void (QOPENGLF_APIENTRYP SecondaryColor3iv)(const GLint *v); - void (QOPENGLF_APIENTRYP SecondaryColor3i)(GLint red, GLint green, GLint blue); - void (QOPENGLF_APIENTRYP SecondaryColor3fv)(const GLfloat *v); - void (QOPENGLF_APIENTRYP SecondaryColor3f)(GLfloat red, GLfloat green, GLfloat blue); - void (QOPENGLF_APIENTRYP SecondaryColor3dv)(const GLdouble *v); - void (QOPENGLF_APIENTRYP SecondaryColor3d)(GLdouble red, GLdouble green, GLdouble blue); - void (QOPENGLF_APIENTRYP SecondaryColor3bv)(const GLbyte *v); - void (QOPENGLF_APIENTRYP SecondaryColor3b)(GLbyte red, GLbyte green, GLbyte blue); - void (QOPENGLF_APIENTRYP FogCoordPointer)(GLenum type, GLsizei stride, const GLvoid *pointer); - void (QOPENGLF_APIENTRYP FogCoorddv)(const GLdouble *coord); - void (QOPENGLF_APIENTRYP FogCoordd)(GLdouble coord); - void (QOPENGLF_APIENTRYP FogCoordfv)(const GLfloat *coord); - void (QOPENGLF_APIENTRYP FogCoordf)(GLfloat coord); - + void(QOPENGLF_APIENTRYP WindowPos3sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP WindowPos3s)(GLshort x, GLshort y, GLshort z); + void(QOPENGLF_APIENTRYP WindowPos3iv)(const GLint *v); + void(QOPENGLF_APIENTRYP WindowPos3i)(GLint x, GLint y, GLint z); + void(QOPENGLF_APIENTRYP WindowPos3fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP WindowPos3f)(GLfloat x, GLfloat y, GLfloat z); + void(QOPENGLF_APIENTRYP WindowPos3dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP WindowPos3d)(GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP WindowPos2sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP WindowPos2s)(GLshort x, GLshort y); + void(QOPENGLF_APIENTRYP WindowPos2iv)(const GLint *v); + void(QOPENGLF_APIENTRYP WindowPos2i)(GLint x, GLint y); + void(QOPENGLF_APIENTRYP WindowPos2fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP WindowPos2f)(GLfloat x, GLfloat y); + void(QOPENGLF_APIENTRYP WindowPos2dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP WindowPos2d)(GLdouble x, GLdouble y); + void(QOPENGLF_APIENTRYP SecondaryColorPointer)(GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer); + void(QOPENGLF_APIENTRYP SecondaryColor3usv)(const GLushort *v); + void(QOPENGLF_APIENTRYP SecondaryColor3us)(GLushort red, GLushort green, GLushort blue); + void(QOPENGLF_APIENTRYP SecondaryColor3uiv)(const GLuint *v); + void(QOPENGLF_APIENTRYP SecondaryColor3ui)(GLuint red, GLuint green, GLuint blue); + void(QOPENGLF_APIENTRYP SecondaryColor3ubv)(const GLubyte *v); + void(QOPENGLF_APIENTRYP SecondaryColor3ub)(GLubyte red, GLubyte green, GLubyte blue); + void(QOPENGLF_APIENTRYP SecondaryColor3sv)(const GLshort *v); + void(QOPENGLF_APIENTRYP SecondaryColor3s)(GLshort red, GLshort green, GLshort blue); + void(QOPENGLF_APIENTRYP SecondaryColor3iv)(const GLint *v); + void(QOPENGLF_APIENTRYP SecondaryColor3i)(GLint red, GLint green, GLint blue); + void(QOPENGLF_APIENTRYP SecondaryColor3fv)(const GLfloat *v); + void(QOPENGLF_APIENTRYP SecondaryColor3f)(GLfloat red, GLfloat green, GLfloat blue); + void(QOPENGLF_APIENTRYP SecondaryColor3dv)(const GLdouble *v); + void(QOPENGLF_APIENTRYP SecondaryColor3d)(GLdouble red, GLdouble green, GLdouble blue); + void(QOPENGLF_APIENTRYP SecondaryColor3bv)(const GLbyte *v); + void(QOPENGLF_APIENTRYP SecondaryColor3b)(GLbyte red, GLbyte green, GLbyte blue); + void(QOPENGLF_APIENTRYP FogCoordPointer)(GLenum type, GLsizei stride, const GLvoid *pointer); + void(QOPENGLF_APIENTRYP FogCoorddv)(const GLdouble *coord); + void(QOPENGLF_APIENTRYP FogCoordd)(GLdouble coord); + void(QOPENGLF_APIENTRYP FogCoordfv)(const GLfloat *coord); + void(QOPENGLF_APIENTRYP FogCoordf)(GLfloat coord); }; -class QOpenGLFunctions_2_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_2_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_2_0_DeprecatedBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 2.0 deprecated functions - void (QOPENGLF_APIENTRYP VertexAttrib4usv)(GLuint index, const GLushort *v); - void (QOPENGLF_APIENTRYP VertexAttrib4uiv)(GLuint index, const GLuint *v); - void (QOPENGLF_APIENTRYP VertexAttrib4ubv)(GLuint index, const GLubyte *v); - void (QOPENGLF_APIENTRYP VertexAttrib4sv)(GLuint index, const GLshort *v); - void (QOPENGLF_APIENTRYP VertexAttrib4s)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); - void (QOPENGLF_APIENTRYP VertexAttrib4iv)(GLuint index, const GLint *v); - void (QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint index, const GLfloat *v); - void (QOPENGLF_APIENTRYP VertexAttrib4f)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void (QOPENGLF_APIENTRYP VertexAttrib4dv)(GLuint index, const GLdouble *v); - void (QOPENGLF_APIENTRYP VertexAttrib4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); - void (QOPENGLF_APIENTRYP VertexAttrib4bv)(GLuint index, const GLbyte *v); - void (QOPENGLF_APIENTRYP VertexAttrib4Nusv)(GLuint index, const GLushort *v); - void (QOPENGLF_APIENTRYP VertexAttrib4Nuiv)(GLuint index, const GLuint *v); - void (QOPENGLF_APIENTRYP VertexAttrib4Nubv)(GLuint index, const GLubyte *v); - void (QOPENGLF_APIENTRYP VertexAttrib4Nub)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); - void (QOPENGLF_APIENTRYP VertexAttrib4Nsv)(GLuint index, const GLshort *v); - void (QOPENGLF_APIENTRYP VertexAttrib4Niv)(GLuint index, const GLint *v); - void (QOPENGLF_APIENTRYP VertexAttrib4Nbv)(GLuint index, const GLbyte *v); - void (QOPENGLF_APIENTRYP VertexAttrib3sv)(GLuint index, const GLshort *v); - void (QOPENGLF_APIENTRYP VertexAttrib3s)(GLuint index, GLshort x, GLshort y, GLshort z); - void (QOPENGLF_APIENTRYP VertexAttrib3fv)(GLuint index, const GLfloat *v); - void (QOPENGLF_APIENTRYP VertexAttrib3f)(GLuint index, GLfloat x, GLfloat y, GLfloat z); - void (QOPENGLF_APIENTRYP VertexAttrib3dv)(GLuint index, const GLdouble *v); - void (QOPENGLF_APIENTRYP VertexAttrib3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z); - void (QOPENGLF_APIENTRYP VertexAttrib2sv)(GLuint index, const GLshort *v); - void (QOPENGLF_APIENTRYP VertexAttrib2s)(GLuint index, GLshort x, GLshort y); - void (QOPENGLF_APIENTRYP VertexAttrib2fv)(GLuint index, const GLfloat *v); - void (QOPENGLF_APIENTRYP VertexAttrib2f)(GLuint index, GLfloat x, GLfloat y); - void (QOPENGLF_APIENTRYP VertexAttrib2dv)(GLuint index, const GLdouble *v); - void (QOPENGLF_APIENTRYP VertexAttrib2d)(GLuint index, GLdouble x, GLdouble y); - void (QOPENGLF_APIENTRYP VertexAttrib1sv)(GLuint index, const GLshort *v); - void (QOPENGLF_APIENTRYP VertexAttrib1s)(GLuint index, GLshort x); - void (QOPENGLF_APIENTRYP VertexAttrib1fv)(GLuint index, const GLfloat *v); - void (QOPENGLF_APIENTRYP VertexAttrib1f)(GLuint index, GLfloat x); - void (QOPENGLF_APIENTRYP VertexAttrib1dv)(GLuint index, const GLdouble *v); - void (QOPENGLF_APIENTRYP VertexAttrib1d)(GLuint index, GLdouble x); - + void(QOPENGLF_APIENTRYP VertexAttrib4usv)(GLuint index, const GLushort *v); + void(QOPENGLF_APIENTRYP VertexAttrib4uiv)(GLuint index, const GLuint *v); + void(QOPENGLF_APIENTRYP VertexAttrib4ubv)(GLuint index, const GLubyte *v); + void(QOPENGLF_APIENTRYP VertexAttrib4sv)(GLuint index, const GLshort *v); + void(QOPENGLF_APIENTRYP VertexAttrib4s)(GLuint index, GLshort x, GLshort y, GLshort z, + GLshort w); + void(QOPENGLF_APIENTRYP VertexAttrib4iv)(GLuint index, const GLint *v); + void(QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint index, const GLfloat *v); + void(QOPENGLF_APIENTRYP VertexAttrib4f)(GLuint index, GLfloat x, GLfloat y, GLfloat z, + GLfloat w); + void(QOPENGLF_APIENTRYP VertexAttrib4dv)(GLuint index, const GLdouble *v); + void(QOPENGLF_APIENTRYP VertexAttrib4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, + GLdouble w); + void(QOPENGLF_APIENTRYP VertexAttrib4bv)(GLuint index, const GLbyte *v); + void(QOPENGLF_APIENTRYP VertexAttrib4Nusv)(GLuint index, const GLushort *v); + void(QOPENGLF_APIENTRYP VertexAttrib4Nuiv)(GLuint index, const GLuint *v); + void(QOPENGLF_APIENTRYP VertexAttrib4Nubv)(GLuint index, const GLubyte *v); + void(QOPENGLF_APIENTRYP VertexAttrib4Nub)(GLuint index, GLubyte x, GLubyte y, GLubyte z, + GLubyte w); + void(QOPENGLF_APIENTRYP VertexAttrib4Nsv)(GLuint index, const GLshort *v); + void(QOPENGLF_APIENTRYP VertexAttrib4Niv)(GLuint index, const GLint *v); + void(QOPENGLF_APIENTRYP VertexAttrib4Nbv)(GLuint index, const GLbyte *v); + void(QOPENGLF_APIENTRYP VertexAttrib3sv)(GLuint index, const GLshort *v); + void(QOPENGLF_APIENTRYP VertexAttrib3s)(GLuint index, GLshort x, GLshort y, GLshort z); + void(QOPENGLF_APIENTRYP VertexAttrib3fv)(GLuint index, const GLfloat *v); + void(QOPENGLF_APIENTRYP VertexAttrib3f)(GLuint index, GLfloat x, GLfloat y, GLfloat z); + void(QOPENGLF_APIENTRYP VertexAttrib3dv)(GLuint index, const GLdouble *v); + void(QOPENGLF_APIENTRYP VertexAttrib3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z); + void(QOPENGLF_APIENTRYP VertexAttrib2sv)(GLuint index, const GLshort *v); + void(QOPENGLF_APIENTRYP VertexAttrib2s)(GLuint index, GLshort x, GLshort y); + void(QOPENGLF_APIENTRYP VertexAttrib2fv)(GLuint index, const GLfloat *v); + void(QOPENGLF_APIENTRYP VertexAttrib2f)(GLuint index, GLfloat x, GLfloat y); + void(QOPENGLF_APIENTRYP VertexAttrib2dv)(GLuint index, const GLdouble *v); + void(QOPENGLF_APIENTRYP VertexAttrib2d)(GLuint index, GLdouble x, GLdouble y); + void(QOPENGLF_APIENTRYP VertexAttrib1sv)(GLuint index, const GLshort *v); + void(QOPENGLF_APIENTRYP VertexAttrib1s)(GLuint index, GLshort x); + void(QOPENGLF_APIENTRYP VertexAttrib1fv)(GLuint index, const GLfloat *v); + void(QOPENGLF_APIENTRYP VertexAttrib1f)(GLuint index, GLfloat x); + void(QOPENGLF_APIENTRYP VertexAttrib1dv)(GLuint index, const GLdouble *v); + void(QOPENGLF_APIENTRYP VertexAttrib1d)(GLuint index, GLdouble x); }; -class QOpenGLFunctions_3_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend -{ -public: +class QOpenGLFunctions_3_0_DeprecatedBackend : public QOpenGLVersionFunctionsBackend { + public: QOpenGLFunctions_3_0_DeprecatedBackend(QOpenGLContext *context); static QOpenGLVersionStatus versionStatus(); // OpenGL 3.0 deprecated functions - void (QOPENGLF_APIENTRYP VertexAttribI4usv)(GLuint index, const GLushort *v); - void (QOPENGLF_APIENTRYP VertexAttribI4ubv)(GLuint index, const GLubyte *v); - void (QOPENGLF_APIENTRYP VertexAttribI4sv)(GLuint index, const GLshort *v); - void (QOPENGLF_APIENTRYP VertexAttribI4bv)(GLuint index, const GLbyte *v); - void (QOPENGLF_APIENTRYP VertexAttribI4uiv)(GLuint index, const GLuint *v); - void (QOPENGLF_APIENTRYP VertexAttribI3uiv)(GLuint index, const GLuint *v); - void (QOPENGLF_APIENTRYP VertexAttribI2uiv)(GLuint index, const GLuint *v); - void (QOPENGLF_APIENTRYP VertexAttribI1uiv)(GLuint index, const GLuint *v); - void (QOPENGLF_APIENTRYP VertexAttribI4iv)(GLuint index, const GLint *v); - void (QOPENGLF_APIENTRYP VertexAttribI3iv)(GLuint index, const GLint *v); - void (QOPENGLF_APIENTRYP VertexAttribI2iv)(GLuint index, const GLint *v); - void (QOPENGLF_APIENTRYP VertexAttribI1iv)(GLuint index, const GLint *v); - void (QOPENGLF_APIENTRYP VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); - void (QOPENGLF_APIENTRYP VertexAttribI3ui)(GLuint index, GLuint x, GLuint y, GLuint z); - void (QOPENGLF_APIENTRYP VertexAttribI2ui)(GLuint index, GLuint x, GLuint y); - void (QOPENGLF_APIENTRYP VertexAttribI1ui)(GLuint index, GLuint x); - void (QOPENGLF_APIENTRYP VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w); - void (QOPENGLF_APIENTRYP VertexAttribI3i)(GLuint index, GLint x, GLint y, GLint z); - void (QOPENGLF_APIENTRYP VertexAttribI2i)(GLuint index, GLint x, GLint y); - void (QOPENGLF_APIENTRYP VertexAttribI1i)(GLuint index, GLint x); - + void(QOPENGLF_APIENTRYP VertexAttribI4usv)(GLuint index, const GLushort *v); + void(QOPENGLF_APIENTRYP VertexAttribI4ubv)(GLuint index, const GLubyte *v); + void(QOPENGLF_APIENTRYP VertexAttribI4sv)(GLuint index, const GLshort *v); + void(QOPENGLF_APIENTRYP VertexAttribI4bv)(GLuint index, const GLbyte *v); + void(QOPENGLF_APIENTRYP VertexAttribI4uiv)(GLuint index, const GLuint *v); + void(QOPENGLF_APIENTRYP VertexAttribI3uiv)(GLuint index, const GLuint *v); + void(QOPENGLF_APIENTRYP VertexAttribI2uiv)(GLuint index, const GLuint *v); + void(QOPENGLF_APIENTRYP VertexAttribI1uiv)(GLuint index, const GLuint *v); + void(QOPENGLF_APIENTRYP VertexAttribI4iv)(GLuint index, const GLint *v); + void(QOPENGLF_APIENTRYP VertexAttribI3iv)(GLuint index, const GLint *v); + void(QOPENGLF_APIENTRYP VertexAttribI2iv)(GLuint index, const GLint *v); + void(QOPENGLF_APIENTRYP VertexAttribI1iv)(GLuint index, const GLint *v); + void(QOPENGLF_APIENTRYP VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void(QOPENGLF_APIENTRYP VertexAttribI3ui)(GLuint index, GLuint x, GLuint y, GLuint z); + void(QOPENGLF_APIENTRYP VertexAttribI2ui)(GLuint index, GLuint x, GLuint y); + void(QOPENGLF_APIENTRYP VertexAttribI1ui)(GLuint index, GLuint x); + void(QOPENGLF_APIENTRYP VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w); + void(QOPENGLF_APIENTRYP VertexAttribI3i)(GLuint index, GLint x, GLint y, GLint z); + void(QOPENGLF_APIENTRYP VertexAttribI2i)(GLuint index, GLint x, GLint y); + void(QOPENGLF_APIENTRYP VertexAttribI1i)(GLuint index, GLint x); }; - #else // No need for backend classes with function pointers with ES2. // All function addresses are independent of context and display. -#endif // !QT_OPENGL_ES_2 +#endif // !QT_OPENGL_ES_2 QT_END_NAMESPACE -#endif // QT_NO_OPENGL +#endif // QT_NO_OPENGL #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5f51be46d..b7ee3687e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,625 +1,611 @@ -cmake_minimum_required(VERSION 3.5) -project(QOwnNotes) - -list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) - -# BEGIN options -option(QON_QT6_BUILD "Build QOwnNotes with Qt6" OFF) -option(DEV_MODE "Build QOwnNotes in developer mode" OFF) -# END options - -if (QON_QT6_BUILD) - set(QT_VERSION_MAJOR 6) - set(QT_DEFAULT_MAJOR_VERSION 6) -else() - set(QT_VERSION_MAJOR 5) -endif() - -# put the QOwnNotes.exe in build directory -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) - -# for intellisence -set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) - -# include some Botan settings -add_subdirectory(libraries/botan) -#include sonnet core directory, required for building plugins -include_directories(libraries/sonnet/src/core) -#some hunspell settings for windows -include(libraries/sonnet/src/plugins/hunspell/hunspell/CMakeLists.txt) - -add_executable(QOwnNotes "") - -if (CMAKE_BUILD_TYPE MATCHES Debug) - message("Debug build configuration detected") - add_definitions(-DQT_DEBUG) -else() - message("Non-debug build configuration detected") -endif() - -set_target_properties(QOwnNotes PROPERTIES - CXX_STANDARD 11 - CXX_STANDARD_REQUIRED ON - AUTOMOC ON - AUTOUIC ON - AUTORCC ON -) - -if (UNIX AND DEV_MODE) - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - target_compile_options(QOwnNotes PRIVATE - -Wall -Wextra -pedantic -Wno-gnu-zero-variadic-macro-arguments -Wno-error=deprecated-declarations - ) - else() - target_compile_options(QOwnNotes PRIVATE - -Wall -Wextra -pedantic -Wno-error=deprecated-declarations - ) - endif() - - # enable werror on linux - if (NOT APPLE) - message("Werror enabled on linux") - target_compile_options(QOwnNotes PRIVATE -Werror) - endif() -endif() - -target_include_directories(QOwnNotes PRIVATE - ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_BINARY_DIR} -) - -# Disable shared library building of libraries -set(BUILD_SHARED_LIBS OFF) -# QHotKey library -# Disable building tests inside QHotKey library -set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) -set(QHOTKEY_EXAMPLES OFF) -add_subdirectory(libraries/qhotkey EXCLUDE_FROM_ALL) - -# FakeVim library -set(CREATE_STATIC_LIBRARY ON) -if(MSVC) - add_compile_definitions(FAKEVIM_STATIC_DEFINE QTCREATOR_UTILS_STATIC_LIB) -endif() -add_subdirectory(libraries/fakevim EXCLUDE_FROM_ALL) -add_subdirectory(libraries/diff_match_patch EXCLUDE_FROM_ALL) - -option(USE_QLITE_HTML "Build using QLiteHtml for preview" OFF) -if (USE_QLITEHTML) - add_definitions(-DUSE_QLITEHTML=1) - add_subdirectory(libraries/qlitehtml EXCLUDE_FROM_ALL) -endif() - -message("Using Qt version ${QT_VERSION_MAJOR}") -set(QT_NO_CREATE_VERSIONLESS_FUNCTIONS ON) - -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS REQUIRED - LinguistTools - Core - Widgets - Gui - Sql - Svg - Network - Xml - PrintSupport - WebSockets - Qml - Concurrent -) - -find_program(CCACHE_FOUND ccache) - -if(CCACHE_FOUND) - message(STATUS "ccache found") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) -endif(CCACHE_FOUND) - -set(RESOURCE_FILES - breeze-qownnotes.qrc - breeze-dark-qownnotes.qrc - qownnotes.qrc - demonotes.qrc - images.qrc - texts.qrc - configurations.qrc - libraries/qmarkdowntextedit/media.qrc - libraries/qdarkstyle/style.qrc - libraries/qkeysequencewidget/qkeysequencewidget/qkeysequencewidget.qrc -) - -set(SOURCE_FILES - dialogs/welcomedialog.cpp - dialogs/welcomedialog.h - dialogs/welcomedialog.ui - dialogs/issueassistantdialog.cpp - dialogs/issueassistantdialog.h - dialogs/issueassistantdialog.ui - dialogs/aboutdialog.cpp - dialogs/aboutdialog.h - dialogs/aboutdialog.ui - dialogs/linkdialog.cpp - dialogs/linkdialog.h - dialogs/linkdialog.ui - dialogs/notediffdialog.cpp - dialogs/notediffdialog.h - dialogs/notediffdialog.ui - dialogs/textdiffdialog.cpp - dialogs/textdiffdialog.h - dialogs/textdiffdialog.ui - dialogs/settingsdialog.cpp - dialogs/settingsdialog.h - dialogs/settingsdialog.ui - dialogs/tododialog.cpp - dialogs/tododialog.h - dialogs/tododialog.ui - dialogs/trashdialog.cpp - dialogs/trashdialog.h - dialogs/trashdialog.ui - dialogs/localtrashdialog.cpp - dialogs/localtrashdialog.h - dialogs/localtrashdialog.ui - dialogs/nextclouddeckdialog.cpp - dialogs/nextclouddeckdialog.h - dialogs/nextclouddeckdialog.ui - dialogs/updatedialog.cpp - dialogs/updatedialog.h - dialogs/updatedialog.ui - dialogs/versiondialog.cpp - dialogs/versiondialog.h - dialogs/versiondialog.ui - dialogs/passworddialog.cpp - dialogs/passworddialog.h - dialogs/passworddialog.ui - dialogs/masterdialog.cpp - dialogs/masterdialog.h - dialogs/tagadddialog.cpp - dialogs/tagadddialog.h - dialogs/tagadddialog.ui - dialogs/sharedialog.cpp - dialogs/sharedialog.h - dialogs/sharedialog.ui - dialogs/evernoteimportdialog.cpp - dialogs/evernoteimportdialog.h - dialogs/evernoteimportdialog.ui - dialogs/joplinimportdialog.cpp - dialogs/joplinimportdialog.h - dialogs/joplinimportdialog.ui - dialogs/serverbookmarksimportdialog.cpp - dialogs/serverbookmarksimportdialog.h - dialogs/serverbookmarksimportdialog.ui - dialogs/storedimagesdialog.cpp - dialogs/storedimagesdialog.h - dialogs/storedimagesdialog.ui - dialogs/storedattachmentsdialog.cpp - dialogs/storedattachmentsdialog.h - dialogs/storedattachmentsdialog.ui - dialogs/scriptrepositorydialog.cpp - dialogs/scriptrepositorydialog.h - dialogs/scriptrepositorydialog.ui - dialogs/dictionarymanagerdialog.cpp - dialogs/dictionarymanagerdialog.h - dialogs/dictionarymanagerdialog.ui - dialogs/actiondialog.cpp - dialogs/actiondialog.h - dialogs/actiondialog.ui - dialogs/tabledialog.cpp - dialogs/tabledialog.h - dialogs/tabledialog.ui - dialogs/notedialog.cpp - dialogs/notedialog.h - dialogs/notedialog.ui - dialogs/websockettokendialog.cpp - dialogs/websockettokendialog.h - dialogs/websockettokendialog.ui - dialogs/imagedialog.cpp - dialogs/imagedialog.h - dialogs/imagedialog.ui - dialogs/commandbar.cpp - dialogs/commandbar.h - dialogs/attachmentdialog.cpp - dialogs/attachmentdialog.h - dialogs/attachmentdialog.ui - dialogs/filedialog.cpp - dialogs/filedialog.h - models/commandmodel.cpp - models/commandmodel.h - entities/calendaritem.cpp - entities/calendaritem.h - entities/note.cpp - entities/note.h - entities/trashitem.cpp - entities/trashitem.h - entities/notesubfolder.cpp - entities/notesubfolder.h - entities/notehistory.cpp - entities/notehistory.h - entities/notefolder.cpp - entities/notefolder.h - entities/cloudconnection.cpp - entities/cloudconnection.h - entities/tag.cpp - entities/tag.h - entities/script.cpp - entities/script.h - helpers/flowlayout.cpp - helpers/flowlayout.h - helpers/htmlentities.cpp - helpers/htmlentities.h - helpers/clientproxy.cpp - helpers/clientproxy.h - helpers/toolbarcontainer.cpp - helpers/toolbarcontainer.h - helpers/qownnotesmarkdownhighlighter.cpp - helpers/qownnotesmarkdownhighlighter.h - helpers/LanguageCache.h - helpers/qownspellchecker.cpp - helpers/qownspellchecker.h - helpers/codetohtmlconverter.cpp - helpers/codetohtmlconverter.h - helpers/nomenuiconstyle.cpp - helpers/nomenuiconstyle.h - api/noteapi.cpp - api/noteapi.h - api/notesubfolderapi.cpp - api/notesubfolderapi.h - api/tagapi.cpp - api/tagapi.h - api/scriptapi.cpp - api/scriptapi.h - libraries/qmarkdowntextedit/linenumberarea.h - libraries/qmarkdowntextedit/qownlanguagedata.cpp - libraries/qmarkdowntextedit/qownlanguagedata.h - libraries/qmarkdowntextedit/markdownhighlighter.cpp - libraries/qmarkdowntextedit/markdownhighlighter.h - libraries/qmarkdowntextedit/qmarkdowntextedit.cpp - libraries/qmarkdowntextedit/qmarkdowntextedit.h - libraries/qmarkdowntextedit/qplaintexteditsearchwidget.cpp - libraries/qmarkdowntextedit/qplaintexteditsearchwidget.h - libraries/qmarkdowntextedit/qplaintexteditsearchwidget.ui - libraries/simplecrypt/simplecrypt.cpp - libraries/simplecrypt/simplecrypt.h - libraries/versionnumber/versionnumber.cpp - libraries/versionnumber/versionnumber.h - libraries/singleapplication/singleapplication.h - libraries/singleapplication/singleapplication.cpp - libraries/singleapplication/singleapplication_p.h - libraries/singleapplication/singleapplication_p.cpp - libraries/qttoolbareditor/src/toolbar_editor.cpp - libraries/qttoolbareditor/src/toolbar_editor.hpp - libraries/qttoolbareditor/src/toolbar_editor.ui - libraries/qtcsv/src/include/qtcsv_global.h - libraries/qtcsv/src/include/abstractdata.h - libraries/qtcsv/src/include/reader.h - libraries/qtcsv/src/sources/reader.cpp - libraries/qtcsv/src/sources/filechecker.h - libraries/qtcsv/src/sources/symbols.h - libraries/qtwaitingspinner/waitingspinnerwidget.h - libraries/qtwaitingspinner/waitingspinnerwidget.cpp - services/databaseservice.cpp - services/databaseservice.h - services/owncloudservice.cpp - services/owncloudservice.h - services/nextclouddeckservice.cpp - services/nextclouddeckservice.h - services/updateservice.cpp - services/updateservice.h - services/metricsservice.cpp - services/metricsservice.h - services/cryptoservice.cpp - services/cryptoservice.h - services/scriptingservice.cpp - services/scriptingservice.h - services/openaiservice.cpp - services/openaiservice.h - services/settingsservice.cpp - services/settingsservice.h - libraries/piwiktracker/piwiktracker.h - libraries/piwiktracker/piwiktracker.cpp - libraries/qkeysequencewidget/qkeysequencewidget/src/qkeysequencewidget_p.h - libraries/qkeysequencewidget/qkeysequencewidget/src/qkeysequencewidget.h - libraries/qkeysequencewidget/qkeysequencewidget/src/qkeysequencewidget.cpp - libraries/sonnet/src/core/backgroundchecker.cpp - libraries/sonnet/src/core/backgroundchecker.h - libraries/sonnet/src/core/backgroundchecker_p.h - libraries/sonnet/src/core/client.cpp - libraries/sonnet/src/core/client_p.h - libraries/sonnet/src/core/core_debug.cpp - libraries/sonnet/src/core/core_debug.h - libraries/sonnet/src/core/guesslanguage.cpp - libraries/sonnet/src/core/guesslanguage.h - libraries/sonnet/src/core/languagefilter.cpp - libraries/sonnet/src/core/languagefilter_p.h - libraries/sonnet/src/core/loader.cpp - libraries/sonnet/src/core/loader_p.h - libraries/sonnet/src/core/settings.cpp - libraries/sonnet/src/core/settings_p.h - libraries/sonnet/src/core/sonnetcore_export.h - libraries/sonnet/src/core/speller.cpp - libraries/sonnet/src/core/speller.h - libraries/sonnet/src/core/spellerplugin.cpp - libraries/sonnet/src/core/spellerplugin_p.h - libraries/sonnet/src/core/textbreaks.cpp - libraries/sonnet/src/core/textbreaks_p.h - libraries/sonnet/src/core/tokenizer.cpp - libraries/sonnet/src/core/tokenizer_p.h - libraries/fuzzy/kfuzzymatcher.cpp - libraries/qr-code-generator/QrCode.hpp - libraries/qr-code-generator/QrCode.cpp - - threads/scriptthread.cpp - threads/scriptthread.h - - widgets/qownnotesmarkdowntextedit.cpp - widgets/qownnotesmarkdowntextedit.h - widgets/navigationwidget.cpp - widgets/navigationwidget.h - widgets/backlinkwidget.cpp - widgets/backlinkwidget.h - widgets/notepreviewwidget.cpp - widgets/notepreviewwidget.h - widgets/combobox.cpp - widgets/combobox.h - widgets/graphicsview.cpp - widgets/graphicsview.h - widgets/scriptlistwidget.cpp - widgets/scriptlistwidget.h - widgets/notefolderlistwidget.cpp - widgets/notefolderlistwidget.h - widgets/fontcolorwidget.ui - widgets/fontcolorwidget.cpp - widgets/fontcolorwidget.h - widgets/logwidget.cpp - widgets/logwidget.h - widgets/logwidget.ui - widgets/label.cpp - widgets/label.h - widgets/qrcodewidget.cpp - widgets/qrcodewidget.h - widgets/lineedit.cpp - widgets/lineedit.h - widgets/passwordlineedit.cpp - widgets/passwordlineedit.h - widgets/scriptsettingwidget.cpp - widgets/scriptsettingwidget.h - widgets/scriptsettingwidget.ui - widgets/qtexteditsearchwidget.cpp - widgets/qtexteditsearchwidget.h - widgets/qtexteditsearchwidget.ui - widgets/notetreewidgetitem.cpp - widgets/notetreewidgetitem.h - widgets/notetreewidgetitem.ui - widgets/notefilepathlabel.cpp - widgets/notefilepathlabel.h - widgets/layoutwidget.cpp - widgets/layoutwidget.h - widgets/layoutwidget.ui - widgets/todoitemtreewidget.cpp - widgets/todoitemtreewidget.h - widgets/htmlpreviewwidget.h - widgets/htmlpreviewwidget.cpp - widgets/notesubfoldertree.cpp - widgets/notesubfoldertree.h - widgets/noterelationscene.cpp - widgets/noterelationscene.h - utils/misc.cpp - utils/misc.h - utils/git.cpp - utils/git.h - utils/cli.cpp - utils/cli.h - utils/gui.cpp - utils/gui.h - utils/schema.cpp - utils/schema.h - utils/urlhandler.h - utils/urlhandler.cpp - build_number.h - main.cpp - mainwindow.cpp - mainwindow.h - mainwindow.ui - release.h - version.h - helpers/fakevimproxy.h - helpers/fakevimproxy.cpp - services/websocketserverservice.cpp - services/websocketserverservice.h - services/webappclientservice.cpp - services/webappclientservice.h - entities/bookmark.h entities/bookmark.cpp - entities/commandsnippet.h entities/commandsnippet.cpp) - -# spellchecker -list(APPEND SOURCE_FILES - libraries/sonnet/src/plugins/hunspell/hunspellclient.cpp - libraries/sonnet/src/plugins/hunspell/hunspellclient.h - libraries/sonnet/src/plugins/hunspell/hunspelldebug.cpp - libraries/sonnet/src/plugins/hunspell/hunspelldebug.h - libraries/sonnet/src/plugins/hunspell/hunspelldict.cpp - libraries/sonnet/src/plugins/hunspell/hunspelldict.h - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/affentry.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/affentry.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/affixmgr.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/affixmgr.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/atypes.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/baseaffix.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/csutil.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/csutil.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/filemgr.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/filemgr.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hashmgr.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hashmgr.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/htypes.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunspell.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunspell.h - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunspell.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunvisapi.h - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunvisapi.h.in - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunzip.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunzip.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/langnum.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/phonet.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/phonet.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/replist.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/replist.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/suggestmgr.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/suggestmgr.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/utf_info.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/w_char.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/firstparser.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/firstparser.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/htmlparser.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/htmlparser.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/latexparser.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/latexparser.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/manparser.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/manparser.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/odfparser.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/odfparser.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/textparser.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/textparser.hxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/xmlparser.cxx - libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/xmlparser.hxx -) - -# md4c -list(APPEND SOURCE_FILES - libraries/md4c/src/md4c.c - libraries/md4c/src/md4c-html.c - libraries/md4c/src/entity.c -) - -# Translation files -SET(QON_TS_FILES - languages/QOwnNotes_en.ts - languages/QOwnNotes_de.ts - languages/QOwnNotes_fr.ts - languages/QOwnNotes_pl.ts - languages/QOwnNotes_zh_CN.ts - languages/QOwnNotes_zh_TW.ts - languages/QOwnNotes_ru.ts - languages/QOwnNotes_pt_BR.ts - languages/QOwnNotes_pt_PT.ts - languages/QOwnNotes_es.ts - languages/QOwnNotes_nl.ts - languages/QOwnNotes_hu.ts - languages/QOwnNotes_ja.ts - languages/QOwnNotes_it.ts - languages/QOwnNotes_ar.ts - languages/QOwnNotes_uk.ts - languages/QOwnNotes_cs.ts - languages/QOwnNotes_hr.ts - languages/QOwnNotes_ca.ts - languages/QOwnNotes_sv.ts - languages/QOwnNotes_id.ts - languages/QOwnNotes_bn.ts - languages/QOwnNotes_tr.ts - languages/QOwnNotes_tl.ts - languages/QOwnNotes_fil.ts - languages/QOwnNotes_ceb.ts - languages/QOwnNotes_hi.ts - languages/QOwnNotes_hil.ts - languages/QOwnNotes_ur.ts - languages/QOwnNotes_fi.ts - languages/QOwnNotes_el.ts - languages/QOwnNotes_gl.ts - languages/QOwnNotes_no.ts - languages/QOwnNotes_da.ts - languages/QOwnNotes_ro.ts - languages/QOwnNotes_sl.ts - languages/QOwnNotes_sk.ts - languages/QOwnNotes_eu.ts - languages/QOwnNotes_sr.ts - languages/QOwnNotes_fa.ts - languages/QOwnNotes_ha.ts - languages/QOwnNotes_bg.ts - languages/QOwnNotes_is.ts - languages/QOwnNotes_pa.ts - languages/QOwnNotes_sq.ts - languages/QOwnNotes_he.ts - languages/QOwnNotes_yi.ts - languages/QOwnNotes_th.ts - languages/QOwnNotes_sn.ts - languages/QOwnNotes_km.ts - languages/QOwnNotes_si.ts - languages/QOwnNotes_zu.ts - languages/QOwnNotes_xh.ts - languages/QOwnNotes_ms.ts - languages/QOwnNotes_mi.ts - languages/QOwnNotes_ga.ts - languages/QOwnNotes_uz.ts - languages/QOwnNotes_vi.ts - languages/QOwnNotes_lv.ts - languages/QOwnNotes_ku.ts - languages/QOwnNotes_lt.ts - languages/QOwnNotes_bs.ts - languages/QOwnNotes_mk.ts - languages/QOwnNotes_ko.ts - languages/QOwnNotes_et.ts -) - -if (QON_QT6_BUILD) - qt6_add_translation(QON_QM_FILES ${QON_TS_FILES}) -else() - qt5_add_translation(QON_QM_FILES ${QON_TS_FILES}) -endif() - -add_custom_target(translations DEPENDS ${QON_QM_FILES}) - -target_sources(QOwnNotes PRIVATE - ${SOURCE_FILES} - ${RESOURCE_FILES} - ${QON_QM_FILES} -) - -# The Qt5::Widgets target will also link Qt::Gui and Qt::Core targets -target_link_libraries(QOwnNotes PRIVATE - Qt${QT_VERSION_MAJOR}::Widgets - Qt${QT_VERSION_MAJOR}::Sql - Qt${QT_VERSION_MAJOR}::Svg - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Xml - Qt${QT_VERSION_MAJOR}::PrintSupport - Qt${QT_VERSION_MAJOR}::WebSockets - Qt${QT_VERSION_MAJOR}::Qml - Qt${QT_VERSION_MAJOR}::Concurrent - QHotkey::QHotkey - Botan::Botan - fakevim - Google::DiffMatchPatch -) - -if (USE_QLITEHTML) - target_link_libraries(QOwnNotes PRIVATE - qlitehtml::qlitehtml - ) -endif() - -if(MINGW OR MSVC) - # Qt 5 does not define UNICODE for CMake - # only qmake automatically define UNICODE - target_compile_definitions(QOwnNotes PRIVATE - UNICODE _UNICODE - ) -endif() - -if(MSVC) - target_compile_definitions(QOwnNotes PRIVATE - NOMINMAX - ) -endif() - -add_compile_definitions(QAPPLICATION_CLASS=QApplication) - -## Installation - -install(TARGETS QOwnNotes DESTINATION bin) -install(DIRECTORY images/icons DESTINATION share/icons/hicolor) -install(FILES PBE.QOwnNotes.desktop DESTINATION share/applications) -if (QON_QT6_BUILD) - install(FILES ${QON_QM_FILES} DESTINATION share/qt6/translations) -else() - install(FILES ${QON_QM_FILES} DESTINATION share/qt5/translations) -endif() +cmake_minimum_required(VERSION 3.5) +project(QOwnNotes) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +# BEGIN options +option(QON_QT6_BUILD "Build QOwnNotes with Qt6" OFF) +option(DEV_MODE "Build QOwnNotes in developer mode" OFF) +# END options + +if(QON_QT6_BUILD) + set(QT_VERSION_MAJOR 6) + set(QT_DEFAULT_MAJOR_VERSION 6) +else() + set(QT_VERSION_MAJOR 5) +endif() + +# put the QOwnNotes.exe in build directory +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +# for intellisence +set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) + +# include some Botan settings +add_subdirectory(libraries/botan) +# include sonnet core directory, required for building plugins +include_directories(libraries/sonnet/src/core) +# some hunspell settings for windows +include(libraries/sonnet/src/plugins/hunspell/hunspell/CMakeLists.txt) + +add_executable(QOwnNotes "") + +if(CMAKE_BUILD_TYPE MATCHES Debug) + message("Debug build configuration detected") + add_definitions(-DQT_DEBUG) +else() + message("Non-debug build configuration detected") +endif() + +set_target_properties( + QOwnNotes + PROPERTIES CXX_STANDARD 11 + CXX_STANDARD_REQUIRED ON + AUTOMOC ON + AUTOUIC ON + AUTORCC ON) + +if(UNIX AND DEV_MODE) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_compile_options( + QOwnNotes + PRIVATE -Wall -Wextra -pedantic -Wno-gnu-zero-variadic-macro-arguments + -Wno-error=deprecated-declarations) + else() + target_compile_options(QOwnNotes PRIVATE -Wall -Wextra -pedantic + -Wno-error=deprecated-declarations) + endif() + + # enable werror on linux + if(NOT APPLE) + message("Werror enabled on linux") + target_compile_options(QOwnNotes PRIVATE -Werror) + endif() +endif() + +target_include_directories(QOwnNotes PRIVATE ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + +# Disable shared library building of libraries +set(BUILD_SHARED_LIBS OFF) +# QHotKey library Disable building tests inside QHotKey library +set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) +set(QHOTKEY_EXAMPLES OFF) +add_subdirectory(libraries/qhotkey EXCLUDE_FROM_ALL) + +# FakeVim library +set(CREATE_STATIC_LIBRARY ON) +if(MSVC) + add_compile_definitions(FAKEVIM_STATIC_DEFINE QTCREATOR_UTILS_STATIC_LIB) +endif() +add_subdirectory(libraries/fakevim EXCLUDE_FROM_ALL) +add_subdirectory(libraries/diff_match_patch EXCLUDE_FROM_ALL) + +option(USE_QLITE_HTML "Build using QLiteHtml for preview" OFF) +if(USE_QLITEHTML) + add_definitions(-DUSE_QLITEHTML=1) + add_subdirectory(libraries/qlitehtml EXCLUDE_FROM_ALL) +endif() + +message("Using Qt version ${QT_VERSION_MAJOR}") +set(QT_NO_CREATE_VERSIONLESS_FUNCTIONS ON) + +find_package( + Qt${QT_VERSION_MAJOR} + COMPONENTS + REQUIRED + LinguistTools + Core + Widgets + Gui + Sql + Svg + Network + Xml + PrintSupport + WebSockets + Qml + Concurrent) + +find_program(CCACHE_FOUND ccache) + +if(CCACHE_FOUND) + message(STATUS "ccache found") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) +endif(CCACHE_FOUND) + +set(RESOURCE_FILES + breeze-qownnotes.qrc + breeze-dark-qownnotes.qrc + qownnotes.qrc + demonotes.qrc + images.qrc + texts.qrc + configurations.qrc + libraries/qmarkdowntextedit/media.qrc + libraries/qdarkstyle/style.qrc + libraries/qkeysequencewidget/qkeysequencewidget/qkeysequencewidget.qrc) + +set(SOURCE_FILES + dialogs/welcomedialog.cpp + dialogs/welcomedialog.h + dialogs/welcomedialog.ui + dialogs/issueassistantdialog.cpp + dialogs/issueassistantdialog.h + dialogs/issueassistantdialog.ui + dialogs/aboutdialog.cpp + dialogs/aboutdialog.h + dialogs/aboutdialog.ui + dialogs/linkdialog.cpp + dialogs/linkdialog.h + dialogs/linkdialog.ui + dialogs/notediffdialog.cpp + dialogs/notediffdialog.h + dialogs/notediffdialog.ui + dialogs/textdiffdialog.cpp + dialogs/textdiffdialog.h + dialogs/textdiffdialog.ui + dialogs/settingsdialog.cpp + dialogs/settingsdialog.h + dialogs/settingsdialog.ui + dialogs/tododialog.cpp + dialogs/tododialog.h + dialogs/tododialog.ui + dialogs/trashdialog.cpp + dialogs/trashdialog.h + dialogs/trashdialog.ui + dialogs/localtrashdialog.cpp + dialogs/localtrashdialog.h + dialogs/localtrashdialog.ui + dialogs/nextclouddeckdialog.cpp + dialogs/nextclouddeckdialog.h + dialogs/nextclouddeckdialog.ui + dialogs/updatedialog.cpp + dialogs/updatedialog.h + dialogs/updatedialog.ui + dialogs/versiondialog.cpp + dialogs/versiondialog.h + dialogs/versiondialog.ui + dialogs/passworddialog.cpp + dialogs/passworddialog.h + dialogs/passworddialog.ui + dialogs/masterdialog.cpp + dialogs/masterdialog.h + dialogs/tagadddialog.cpp + dialogs/tagadddialog.h + dialogs/tagadddialog.ui + dialogs/sharedialog.cpp + dialogs/sharedialog.h + dialogs/sharedialog.ui + dialogs/evernoteimportdialog.cpp + dialogs/evernoteimportdialog.h + dialogs/evernoteimportdialog.ui + dialogs/joplinimportdialog.cpp + dialogs/joplinimportdialog.h + dialogs/joplinimportdialog.ui + dialogs/serverbookmarksimportdialog.cpp + dialogs/serverbookmarksimportdialog.h + dialogs/serverbookmarksimportdialog.ui + dialogs/storedimagesdialog.cpp + dialogs/storedimagesdialog.h + dialogs/storedimagesdialog.ui + dialogs/storedattachmentsdialog.cpp + dialogs/storedattachmentsdialog.h + dialogs/storedattachmentsdialog.ui + dialogs/scriptrepositorydialog.cpp + dialogs/scriptrepositorydialog.h + dialogs/scriptrepositorydialog.ui + dialogs/dictionarymanagerdialog.cpp + dialogs/dictionarymanagerdialog.h + dialogs/dictionarymanagerdialog.ui + dialogs/actiondialog.cpp + dialogs/actiondialog.h + dialogs/actiondialog.ui + dialogs/tabledialog.cpp + dialogs/tabledialog.h + dialogs/tabledialog.ui + dialogs/notedialog.cpp + dialogs/notedialog.h + dialogs/notedialog.ui + dialogs/websockettokendialog.cpp + dialogs/websockettokendialog.h + dialogs/websockettokendialog.ui + dialogs/imagedialog.cpp + dialogs/imagedialog.h + dialogs/imagedialog.ui + dialogs/commandbar.cpp + dialogs/commandbar.h + dialogs/attachmentdialog.cpp + dialogs/attachmentdialog.h + dialogs/attachmentdialog.ui + dialogs/filedialog.cpp + dialogs/filedialog.h + models/commandmodel.cpp + models/commandmodel.h + entities/calendaritem.cpp + entities/calendaritem.h + entities/note.cpp + entities/note.h + entities/trashitem.cpp + entities/trashitem.h + entities/notesubfolder.cpp + entities/notesubfolder.h + entities/notehistory.cpp + entities/notehistory.h + entities/notefolder.cpp + entities/notefolder.h + entities/cloudconnection.cpp + entities/cloudconnection.h + entities/tag.cpp + entities/tag.h + entities/script.cpp + entities/script.h + helpers/flowlayout.cpp + helpers/flowlayout.h + helpers/htmlentities.cpp + helpers/htmlentities.h + helpers/clientproxy.cpp + helpers/clientproxy.h + helpers/toolbarcontainer.cpp + helpers/toolbarcontainer.h + helpers/qownnotesmarkdownhighlighter.cpp + helpers/qownnotesmarkdownhighlighter.h + helpers/LanguageCache.h + helpers/qownspellchecker.cpp + helpers/qownspellchecker.h + helpers/codetohtmlconverter.cpp + helpers/codetohtmlconverter.h + helpers/nomenuiconstyle.cpp + helpers/nomenuiconstyle.h + api/noteapi.cpp + api/noteapi.h + api/notesubfolderapi.cpp + api/notesubfolderapi.h + api/tagapi.cpp + api/tagapi.h + api/scriptapi.cpp + api/scriptapi.h + libraries/qmarkdowntextedit/linenumberarea.h + libraries/qmarkdowntextedit/qownlanguagedata.cpp + libraries/qmarkdowntextedit/qownlanguagedata.h + libraries/qmarkdowntextedit/markdownhighlighter.cpp + libraries/qmarkdowntextedit/markdownhighlighter.h + libraries/qmarkdowntextedit/qmarkdowntextedit.cpp + libraries/qmarkdowntextedit/qmarkdowntextedit.h + libraries/qmarkdowntextedit/qplaintexteditsearchwidget.cpp + libraries/qmarkdowntextedit/qplaintexteditsearchwidget.h + libraries/qmarkdowntextedit/qplaintexteditsearchwidget.ui + libraries/simplecrypt/simplecrypt.cpp + libraries/simplecrypt/simplecrypt.h + libraries/versionnumber/versionnumber.cpp + libraries/versionnumber/versionnumber.h + libraries/singleapplication/singleapplication.h + libraries/singleapplication/singleapplication.cpp + libraries/singleapplication/singleapplication_p.h + libraries/singleapplication/singleapplication_p.cpp + libraries/qttoolbareditor/src/toolbar_editor.cpp + libraries/qttoolbareditor/src/toolbar_editor.hpp + libraries/qttoolbareditor/src/toolbar_editor.ui + libraries/qtcsv/src/include/qtcsv_global.h + libraries/qtcsv/src/include/abstractdata.h + libraries/qtcsv/src/include/reader.h + libraries/qtcsv/src/sources/reader.cpp + libraries/qtcsv/src/sources/filechecker.h + libraries/qtcsv/src/sources/symbols.h + libraries/qtwaitingspinner/waitingspinnerwidget.h + libraries/qtwaitingspinner/waitingspinnerwidget.cpp + services/databaseservice.cpp + services/databaseservice.h + services/owncloudservice.cpp + services/owncloudservice.h + services/nextclouddeckservice.cpp + services/nextclouddeckservice.h + services/updateservice.cpp + services/updateservice.h + services/metricsservice.cpp + services/metricsservice.h + services/cryptoservice.cpp + services/cryptoservice.h + services/scriptingservice.cpp + services/scriptingservice.h + services/openaiservice.cpp + services/openaiservice.h + services/settingsservice.cpp + services/settingsservice.h + libraries/piwiktracker/piwiktracker.h + libraries/piwiktracker/piwiktracker.cpp + libraries/qkeysequencewidget/qkeysequencewidget/src/qkeysequencewidget_p.h + libraries/qkeysequencewidget/qkeysequencewidget/src/qkeysequencewidget.h + libraries/qkeysequencewidget/qkeysequencewidget/src/qkeysequencewidget.cpp + libraries/sonnet/src/core/backgroundchecker.cpp + libraries/sonnet/src/core/backgroundchecker.h + libraries/sonnet/src/core/backgroundchecker_p.h + libraries/sonnet/src/core/client.cpp + libraries/sonnet/src/core/client_p.h + libraries/sonnet/src/core/core_debug.cpp + libraries/sonnet/src/core/core_debug.h + libraries/sonnet/src/core/guesslanguage.cpp + libraries/sonnet/src/core/guesslanguage.h + libraries/sonnet/src/core/languagefilter.cpp + libraries/sonnet/src/core/languagefilter_p.h + libraries/sonnet/src/core/loader.cpp + libraries/sonnet/src/core/loader_p.h + libraries/sonnet/src/core/settings.cpp + libraries/sonnet/src/core/settings_p.h + libraries/sonnet/src/core/sonnetcore_export.h + libraries/sonnet/src/core/speller.cpp + libraries/sonnet/src/core/speller.h + libraries/sonnet/src/core/spellerplugin.cpp + libraries/sonnet/src/core/spellerplugin_p.h + libraries/sonnet/src/core/textbreaks.cpp + libraries/sonnet/src/core/textbreaks_p.h + libraries/sonnet/src/core/tokenizer.cpp + libraries/sonnet/src/core/tokenizer_p.h + libraries/fuzzy/kfuzzymatcher.cpp + libraries/qr-code-generator/QrCode.hpp + libraries/qr-code-generator/QrCode.cpp + threads/scriptthread.cpp + threads/scriptthread.h + widgets/qownnotesmarkdowntextedit.cpp + widgets/qownnotesmarkdowntextedit.h + widgets/navigationwidget.cpp + widgets/navigationwidget.h + widgets/backlinkwidget.cpp + widgets/backlinkwidget.h + widgets/notepreviewwidget.cpp + widgets/notepreviewwidget.h + widgets/combobox.cpp + widgets/combobox.h + widgets/graphicsview.cpp + widgets/graphicsview.h + widgets/scriptlistwidget.cpp + widgets/scriptlistwidget.h + widgets/notefolderlistwidget.cpp + widgets/notefolderlistwidget.h + widgets/fontcolorwidget.ui + widgets/fontcolorwidget.cpp + widgets/fontcolorwidget.h + widgets/logwidget.cpp + widgets/logwidget.h + widgets/logwidget.ui + widgets/label.cpp + widgets/label.h + widgets/qrcodewidget.cpp + widgets/qrcodewidget.h + widgets/lineedit.cpp + widgets/lineedit.h + widgets/passwordlineedit.cpp + widgets/passwordlineedit.h + widgets/scriptsettingwidget.cpp + widgets/scriptsettingwidget.h + widgets/scriptsettingwidget.ui + widgets/qtexteditsearchwidget.cpp + widgets/qtexteditsearchwidget.h + widgets/qtexteditsearchwidget.ui + widgets/notetreewidgetitem.cpp + widgets/notetreewidgetitem.h + widgets/notetreewidgetitem.ui + widgets/notefilepathlabel.cpp + widgets/notefilepathlabel.h + widgets/layoutwidget.cpp + widgets/layoutwidget.h + widgets/layoutwidget.ui + widgets/todoitemtreewidget.cpp + widgets/todoitemtreewidget.h + widgets/htmlpreviewwidget.h + widgets/htmlpreviewwidget.cpp + widgets/notesubfoldertree.cpp + widgets/notesubfoldertree.h + widgets/noterelationscene.cpp + widgets/noterelationscene.h + utils/misc.cpp + utils/misc.h + utils/git.cpp + utils/git.h + utils/cli.cpp + utils/cli.h + utils/gui.cpp + utils/gui.h + utils/schema.cpp + utils/schema.h + utils/urlhandler.h + utils/urlhandler.cpp + build_number.h + main.cpp + mainwindow.cpp + mainwindow.h + mainwindow.ui + release.h + version.h + helpers/fakevimproxy.h + helpers/fakevimproxy.cpp + services/websocketserverservice.cpp + services/websocketserverservice.h + services/webappclientservice.cpp + services/webappclientservice.h + entities/bookmark.h + entities/bookmark.cpp + entities/commandsnippet.h + entities/commandsnippet.cpp) + +# spellchecker +list( + APPEND + SOURCE_FILES + libraries/sonnet/src/plugins/hunspell/hunspellclient.cpp + libraries/sonnet/src/plugins/hunspell/hunspellclient.h + libraries/sonnet/src/plugins/hunspell/hunspelldebug.cpp + libraries/sonnet/src/plugins/hunspell/hunspelldebug.h + libraries/sonnet/src/plugins/hunspell/hunspelldict.cpp + libraries/sonnet/src/plugins/hunspell/hunspelldict.h + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/affentry.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/affentry.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/affixmgr.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/affixmgr.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/atypes.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/baseaffix.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/csutil.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/csutil.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/filemgr.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/filemgr.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hashmgr.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hashmgr.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/htypes.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunspell.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunspell.h + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunspell.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunvisapi.h + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunvisapi.h.in + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunzip.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/hunzip.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/langnum.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/phonet.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/phonet.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/replist.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/replist.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/suggestmgr.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/suggestmgr.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/utf_info.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/hunspell/w_char.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/firstparser.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/firstparser.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/htmlparser.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/htmlparser.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/latexparser.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/latexparser.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/manparser.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/manparser.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/odfparser.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/odfparser.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/textparser.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/textparser.hxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/xmlparser.cxx + libraries/sonnet/src/plugins/hunspell/hunspell/src/parsers/xmlparser.hxx) + +# md4c +list(APPEND SOURCE_FILES libraries/md4c/src/md4c.c + libraries/md4c/src/md4c-html.c libraries/md4c/src/entity.c) + +# Translation files +set(QON_TS_FILES + languages/QOwnNotes_en.ts + languages/QOwnNotes_de.ts + languages/QOwnNotes_fr.ts + languages/QOwnNotes_pl.ts + languages/QOwnNotes_zh_CN.ts + languages/QOwnNotes_zh_TW.ts + languages/QOwnNotes_ru.ts + languages/QOwnNotes_pt_BR.ts + languages/QOwnNotes_pt_PT.ts + languages/QOwnNotes_es.ts + languages/QOwnNotes_nl.ts + languages/QOwnNotes_hu.ts + languages/QOwnNotes_ja.ts + languages/QOwnNotes_it.ts + languages/QOwnNotes_ar.ts + languages/QOwnNotes_uk.ts + languages/QOwnNotes_cs.ts + languages/QOwnNotes_hr.ts + languages/QOwnNotes_ca.ts + languages/QOwnNotes_sv.ts + languages/QOwnNotes_id.ts + languages/QOwnNotes_bn.ts + languages/QOwnNotes_tr.ts + languages/QOwnNotes_tl.ts + languages/QOwnNotes_fil.ts + languages/QOwnNotes_ceb.ts + languages/QOwnNotes_hi.ts + languages/QOwnNotes_hil.ts + languages/QOwnNotes_ur.ts + languages/QOwnNotes_fi.ts + languages/QOwnNotes_el.ts + languages/QOwnNotes_gl.ts + languages/QOwnNotes_no.ts + languages/QOwnNotes_da.ts + languages/QOwnNotes_ro.ts + languages/QOwnNotes_sl.ts + languages/QOwnNotes_sk.ts + languages/QOwnNotes_eu.ts + languages/QOwnNotes_sr.ts + languages/QOwnNotes_fa.ts + languages/QOwnNotes_ha.ts + languages/QOwnNotes_bg.ts + languages/QOwnNotes_is.ts + languages/QOwnNotes_pa.ts + languages/QOwnNotes_sq.ts + languages/QOwnNotes_he.ts + languages/QOwnNotes_yi.ts + languages/QOwnNotes_th.ts + languages/QOwnNotes_sn.ts + languages/QOwnNotes_km.ts + languages/QOwnNotes_si.ts + languages/QOwnNotes_zu.ts + languages/QOwnNotes_xh.ts + languages/QOwnNotes_ms.ts + languages/QOwnNotes_mi.ts + languages/QOwnNotes_ga.ts + languages/QOwnNotes_uz.ts + languages/QOwnNotes_vi.ts + languages/QOwnNotes_lv.ts + languages/QOwnNotes_ku.ts + languages/QOwnNotes_lt.ts + languages/QOwnNotes_bs.ts + languages/QOwnNotes_mk.ts + languages/QOwnNotes_ko.ts + languages/QOwnNotes_et.ts) + +if(QON_QT6_BUILD) + qt6_add_translation(QON_QM_FILES ${QON_TS_FILES}) +else() + qt5_add_translation(QON_QM_FILES ${QON_TS_FILES}) +endif() + +add_custom_target(translations DEPENDS ${QON_QM_FILES}) + +target_sources(QOwnNotes PRIVATE ${SOURCE_FILES} ${RESOURCE_FILES} + ${QON_QM_FILES}) + +# The Qt5::Widgets target will also link Qt::Gui and Qt::Core targets +target_link_libraries( + QOwnNotes + PRIVATE Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Sql + Qt${QT_VERSION_MAJOR}::Svg + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Xml + Qt${QT_VERSION_MAJOR}::PrintSupport + Qt${QT_VERSION_MAJOR}::WebSockets + Qt${QT_VERSION_MAJOR}::Qml + Qt${QT_VERSION_MAJOR}::Concurrent + QHotkey::QHotkey + Botan::Botan + fakevim + Google::DiffMatchPatch) + +if(USE_QLITEHTML) + target_link_libraries(QOwnNotes PRIVATE qlitehtml::qlitehtml) +endif() + +if(MINGW OR MSVC) + # Qt 5 does not define UNICODE for CMake only qmake automatically define + # UNICODE + target_compile_definitions(QOwnNotes PRIVATE UNICODE _UNICODE) +endif() + +if(MSVC) + target_compile_definitions(QOwnNotes PRIVATE NOMINMAX) +endif() + +add_compile_definitions(QAPPLICATION_CLASS=QApplication) + +# Installation + +install(TARGETS QOwnNotes DESTINATION bin) +install(DIRECTORY images/icons DESTINATION share/icons/hicolor) +install(FILES PBE.QOwnNotes.desktop DESTINATION share/applications) +if(QON_QT6_BUILD) + install(FILES ${QON_QM_FILES} DESTINATION share/qt6/translations) +else() + install(FILES ${QON_QM_FILES} DESTINATION share/qt5/translations) +endif() diff --git a/src/cmake/FindBotan2.cmake b/src/cmake/FindBotan2.cmake index c7b3490bc..ddbe77be7 100644 --- a/src/cmake/FindBotan2.cmake +++ b/src/cmake/FindBotan2.cmake @@ -6,12 +6,12 @@ Searching system installed Botan 2 library using PkgConfig #]] if(MSVC OR MINGW) - message(FATAL_ERROR "Using system Botan 2 library in Window not supported") + message(FATAL_ERROR "Using system Botan 2 library in Window not supported") endif() if(TARGET Botan2::Botan2) - message(STATUS "Target Botan::Botan already exists. Skipping searching") - return() + message(STATUS "Target Botan::Botan already exists. Skipping searching") + return() endif() find_package(PkgConfig REQUIRED QUIET) diff --git a/src/libraries/botan/CMakeLists.txt b/src/libraries/botan/CMakeLists.txt index a19f0d891..31cff71bf 100644 --- a/src/libraries/botan/CMakeLists.txt +++ b/src/libraries/botan/CMakeLists.txt @@ -1,137 +1,97 @@ -cmake_minimum_required(VERSION 3.5) -project(Botan) - -option(BUILD_WITH_SYSTEM_BOTAN "Build using system installed Botan 2 crypto library" OFF) - -add_library(botan STATIC "") -add_library(Botan::Botan ALIAS botan) - -target_sources(botan PRIVATE - botanwrapper.h - botanwrapper.cpp -) - -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) - -target_link_libraries(botan PUBLIC Qt${QT_VERSION_MAJOR}::Core) - -target_include_directories(botan PUBLIC ${CMAKE_CURRENT_LIST_DIR}) - -if(BUILD_WITH_SYSTEM_BOTAN) - find_package(Botan2 REQUIRED) - if(NOT TARGET Botan2::Botan2) - message(FATAL_ERROR "Could not find system Botan 2 library using PkgConfig") - endif() - - target_link_libraries(botan PUBLIC Botan2::Botan2) - - target_compile_definitions(botan PUBLIC USE_SYSTEM_BOTAN) - - # Instead of put next lines into else() block - # it is better to just return - return() -endif() - - -target_sources(botan PRIVATE - botan.h - botan.cpp - botan_internal.h -) - - -# add some Botan defines for Linux -if(UNIX) - # Append some definitions as PRIVATE only - # if they used only in cpp and botan_internal header - target_compile_definitions(botan PRIVATE - BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM - ) -endif() -if(CMAKE_SYSTEM_NAME MATCHES "Linux") - target_compile_definitions(botan PRIVATE - BOTAN_TARGET_OS_HAS_CLOCK_GETTIME - BOTAN_TARGET_OS_HAS_POSIX_MLOCK - BOTAN_TARGET_OS_HAS_POSIX1 - ) -endif() -if(APPLE) - target_compile_definitions(botan PRIVATE - BOTAN_TARGET_OS_HAS_POSIX1 - ) -endif() - -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_definitions(botan PUBLIC BOTAN_BUILD_COMPILER_IS_GCC) -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - target_compile_definitions(botan PUBLIC BOTAN_BUILD_COMPILER_IS_CLANG) -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - target_compile_definitions(botan PRIVATE BOTAN_BUILD_COMPILER_IS_INTEL) -endif() - - -if(CMAKE_SYSTEM_PROCESSOR MATCHES "(i386|i686|x86_64|AMD64)") - if(CMAKE_SIZEOF_VOID_P EQUAL 4) - target_compile_definitions(botan PUBLIC - BOTAN_TARGET_CPU_IS_X86_FAMILY - BOTAN_TARGET_ARCH_IS_X86_32 - ) - elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) - target_compile_definitions(botan PUBLIC - BOTAN_TARGET_CPU_IS_X86_FAMILY - BOTAN_TARGET_ARCH_IS_X86_64 - BOTAN_TARGET_CPU_HAS_NATIVE_64BIT - ) - endif() -endif() - -if(WIN32) - target_compile_definitions(botan PRIVATE - BOTAN_TARGET_OS_IS_WINDOWS - BOTAN_TARGET_OS_HAS_WIN32 - BOTAN_HAS_ENTROPY_SRC_WIN32 - ) - if(MSVC) - # TODO Find analog for: - # QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHs - target_compile_options(botan PUBLIC - "-EHs" "-wd4251" "-wd4290" "-wd4250" - ) - target_compile_definitions(botan PRIVATE - _SCL_SECURE_NO_WARNINGS - _CRT_SECURE_NO_WARNINGS - ) - target_compile_definitions(botan PUBLIC - BOTAN_BUILD_COMPILER_IS_MSVC - ) - if(NOT (MSVC_VERSION LESS 1900)) - # For included library binary ABI does not matter - # so disable warning - target_compile_definitions(botan PRIVATE - _ENABLE_EXTENDED_ALIGNED_STORAGE - ) - endif() - else() - target_compile_options(botan PRIVATE - "-fpermissive" "-finline-functions" "-Wno-long-long" - ) - endif() -endif() - -if(UNIX AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set_target_properties(botan PROPERTIES - POSITION_INDEPENDENT_CODE ON - ) - target_compile_options(botan PRIVATE - "-fpermissive" "-finline-functions" "-Wno-long-long" - ) -endif() - -if(CMAKE_SYSTEM_NAME MATCHES "(Linux|FreeBSD)") - target_link_libraries(botan PRIVATE - rt - ) - target_compile_definitions(botan PRIVATE - BOTAN_TARGET_OS_HAS_GETAUXVAL - ) -endif() +cmake_minimum_required(VERSION 3.5) +project(Botan) + +option(BUILD_WITH_SYSTEM_BOTAN + "Build using system installed Botan 2 crypto library" OFF) + +add_library(botan STATIC "") +add_library(Botan::Botan ALIAS botan) + +target_sources(botan PRIVATE botanwrapper.h botanwrapper.cpp) + +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) + +target_link_libraries(botan PUBLIC Qt${QT_VERSION_MAJOR}::Core) + +target_include_directories(botan PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + +if(BUILD_WITH_SYSTEM_BOTAN) + find_package(Botan2 REQUIRED) + if(NOT TARGET Botan2::Botan2) + message(FATAL_ERROR "Could not find system Botan 2 library using PkgConfig") + endif() + + target_link_libraries(botan PUBLIC Botan2::Botan2) + + target_compile_definitions(botan PUBLIC USE_SYSTEM_BOTAN) + + # Instead of put next lines into else() block it is better to just return + return() +endif() + +target_sources(botan PRIVATE botan.h botan.cpp botan_internal.h) + +# add some Botan defines for Linux +if(UNIX) + # Append some definitions as PRIVATE only if they used only in cpp and + # botan_internal header + target_compile_definitions(botan PRIVATE BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) +endif() +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + target_compile_definitions( + botan PRIVATE BOTAN_TARGET_OS_HAS_CLOCK_GETTIME + BOTAN_TARGET_OS_HAS_POSIX_MLOCK BOTAN_TARGET_OS_HAS_POSIX1) +endif() +if(APPLE) + target_compile_definitions(botan PRIVATE BOTAN_TARGET_OS_HAS_POSIX1) +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_definitions(botan PUBLIC BOTAN_BUILD_COMPILER_IS_GCC) +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_definitions(botan PUBLIC BOTAN_BUILD_COMPILER_IS_CLANG) +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + target_compile_definitions(botan PRIVATE BOTAN_BUILD_COMPILER_IS_INTEL) +endif() + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "(i386|i686|x86_64|AMD64)") + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_compile_definitions(botan PUBLIC BOTAN_TARGET_CPU_IS_X86_FAMILY + BOTAN_TARGET_ARCH_IS_X86_32) + elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) + target_compile_definitions( + botan PUBLIC BOTAN_TARGET_CPU_IS_X86_FAMILY BOTAN_TARGET_ARCH_IS_X86_64 + BOTAN_TARGET_CPU_HAS_NATIVE_64BIT) + endif() +endif() + +if(WIN32) + target_compile_definitions( + botan PRIVATE BOTAN_TARGET_OS_IS_WINDOWS BOTAN_TARGET_OS_HAS_WIN32 + BOTAN_HAS_ENTROPY_SRC_WIN32) + if(MSVC) + # TODO Find analog for: QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHs + target_compile_options(botan PUBLIC "-EHs" "-wd4251" "-wd4290" "-wd4250") + target_compile_definitions(botan PRIVATE _SCL_SECURE_NO_WARNINGS + _CRT_SECURE_NO_WARNINGS) + target_compile_definitions(botan PUBLIC BOTAN_BUILD_COMPILER_IS_MSVC) + if(NOT (MSVC_VERSION LESS 1900)) + # For included library binary ABI does not matter so disable warning + target_compile_definitions(botan PRIVATE _ENABLE_EXTENDED_ALIGNED_STORAGE) + endif() + else() + target_compile_options(botan PRIVATE "-fpermissive" "-finline-functions" + "-Wno-long-long") + endif() +endif() + +if(UNIX AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set_target_properties(botan PROPERTIES POSITION_INDEPENDENT_CODE ON) + target_compile_options(botan PRIVATE "-fpermissive" "-finline-functions" + "-Wno-long-long") +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "(Linux|FreeBSD)") + target_link_libraries(botan PRIVATE rt) + target_compile_definitions(botan PRIVATE BOTAN_TARGET_OS_HAS_GETAUXVAL) +endif() diff --git a/src/libraries/botan/botan.cpp b/src/libraries/botan/botan.cpp index 976b58d96..1e49c28ef 100644 --- a/src/libraries/botan/botan.cpp +++ b/src/libraries/botan/botan.cpp @@ -1,111 +1,99 @@ /* -* Botan 2.12.0 Amalgamation -* (C) 1999-2018 The Botan Authors -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Botan 2.12.0 Amalgamation + * (C) 1999-2018 The Botan Authors + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #include "botan.h" + #include "botan_internal.h" /* -* AES -* (C) 1999-2010,2015,2017,2018 Jack Lloyd -* -* Based on the public domain reference implementation by Paulo Baretto -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * AES + * (C) 1999-2010,2015,2017,2018 Jack Lloyd + * + * Based on the public domain reference implementation by Paulo Baretto + * + * Botan is released under the Simplified BSD License (see license.txt) + */ /* -* This implementation is based on table lookups which are known to be -* vulnerable to timing and cache based side channel attacks. Some -* countermeasures are used which may be helpful in some situations: -* -* - Only a single 256-word T-table is used, with rotations applied. -* Most implementations use 4 (or sometimes 5) T-tables, which leaks -* much more information via cache usage. -* -* - The TE and TD tables are computed at runtime to avoid flush+reload -* attacks using clflush. As different processes will not share the -* same underlying table data, an attacker can't manipulate another -* processes cache lines via their shared reference to the library -* read only segment. (However, prime+probe attacks are still possible.) -* -* - Each cache line of the lookup tables is accessed at the beginning -* of each call to encrypt or decrypt. (See the Z variable below) -* -* If available SSSE3 or AES-NI are used instead of this version, as both -* are faster and immune to side channel attacks. -* -* Some AES cache timing papers for reference: -* -* "Software mitigations to hedge AES against cache-based software side -* channel vulnerabilities" https://eprint.iacr.org/2006/052.pdf -* -* "Cache Games - Bringing Access-Based Cache Attacks on AES to Practice" -* http://www.ieee-security.org/TC/SP2011/PAPERS/2011/paper031.pdf -* -* "Cache-Collision Timing Attacks Against AES" Bonneau, Mironov -* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.88.4753 -*/ + * This implementation is based on table lookups which are known to be + * vulnerable to timing and cache based side channel attacks. Some + * countermeasures are used which may be helpful in some situations: + * + * - Only a single 256-word T-table is used, with rotations applied. + * Most implementations use 4 (or sometimes 5) T-tables, which leaks + * much more information via cache usage. + * + * - The TE and TD tables are computed at runtime to avoid flush+reload + * attacks using clflush. As different processes will not share the + * same underlying table data, an attacker can't manipulate another + * processes cache lines via their shared reference to the library + * read only segment. (However, prime+probe attacks are still possible.) + * + * - Each cache line of the lookup tables is accessed at the beginning + * of each call to encrypt or decrypt. (See the Z variable below) + * + * If available SSSE3 or AES-NI are used instead of this version, as both + * are faster and immune to side channel attacks. + * + * Some AES cache timing papers for reference: + * + * "Software mitigations to hedge AES against cache-based software side + * channel vulnerabilities" https://eprint.iacr.org/2006/052.pdf + * + * "Cache Games - Bringing Access-Based Cache Attacks on AES to Practice" + * http://www.ieee-security.org/TC/SP2011/PAPERS/2011/paper031.pdf + * + * "Cache-Collision Timing Attacks Against AES" Bonneau, Mironov + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.88.4753 + */ namespace Botan { namespace { -alignas(64) -const uint8_t SE[256] = { - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, - 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, - 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, - 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, - 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, - 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, - 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, - 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, - 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, - 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, - 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, - 0xB0, 0x54, 0xBB, 0x16 }; +alignas(64) const uint8_t SE[256] = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}; -alignas(64) -const uint8_t SD[256] = { - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, - 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, - 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, - 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, - 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, - 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, - 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, - 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, - 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, - 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0C, 0x7D }; +alignas(64) const uint8_t SD[256] = { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D}; -inline constexpr uint8_t xtime(uint8_t s) { return static_cast(s << 1) ^ ((s >> 7) * 0x1B); } +inline constexpr uint8_t xtime(uint8_t s) { + return static_cast(s << 1) ^ ((s >> 7) * 0x1B); +} inline constexpr uint8_t xtime4(uint8_t s) { return xtime(xtime(s)); } inline constexpr uint8_t xtime8(uint8_t s) { return xtime(xtime(xtime(s))); } @@ -115,378 +103,324 @@ inline constexpr uint8_t xtime11(uint8_t s) { return xtime8(s) ^ xtime(s) ^ s; } inline constexpr uint8_t xtime13(uint8_t s) { return xtime8(s) ^ xtime4(s) ^ s; } inline constexpr uint8_t xtime14(uint8_t s) { return xtime8(s) ^ xtime4(s) ^ xtime(s); } -inline uint32_t SE_word(uint32_t x) - { - return make_uint32(SE[get_byte(0, x)], - SE[get_byte(1, x)], - SE[get_byte(2, x)], - SE[get_byte(3, x)]); - } +inline uint32_t SE_word(uint32_t x) { + return make_uint32(SE[get_byte(0, x)], SE[get_byte(1, x)], SE[get_byte(2, x)], + SE[get_byte(3, x)]); +} -const uint32_t* AES_TE() - { - class TE_Table final - { - public: - TE_Table() - { +const uint32_t* AES_TE() { + class TE_Table final { + public: + TE_Table() { uint32_t* p = reinterpret_cast(&data); - for(size_t i = 0; i != 256; ++i) - { - const uint8_t s = SE[i]; - p[i] = make_uint32(xtime(s), s, s, xtime3(s)); - } + for (size_t i = 0; i != 256; ++i) { + const uint8_t s = SE[i]; + p[i] = make_uint32(xtime(s), s, s, xtime3(s)); } + } - const uint32_t* ptr() const - { - return reinterpret_cast(&data); - } - private: - std::aligned_storage<256*sizeof(uint32_t), 64>::type data; - }; + const uint32_t* ptr() const { return reinterpret_cast(&data); } - static TE_Table table; - return table.ptr(); - } + private: + std::aligned_storage<256 * sizeof(uint32_t), 64>::type data; + }; -const uint32_t* AES_TD() - { - class TD_Table final - { - public: - TD_Table() - { + static TE_Table table; + return table.ptr(); +} + +const uint32_t* AES_TD() { + class TD_Table final { + public: + TD_Table() { uint32_t* p = reinterpret_cast(&data); - for(size_t i = 0; i != 256; ++i) - { - const uint8_t s = SD[i]; - p[i] = make_uint32(xtime14(s), xtime9(s), xtime13(s), xtime11(s)); - } + for (size_t i = 0; i != 256; ++i) { + const uint8_t s = SD[i]; + p[i] = make_uint32(xtime14(s), xtime9(s), xtime13(s), xtime11(s)); } + } - const uint32_t* ptr() const - { - return reinterpret_cast(&data); - } - private: - std::aligned_storage<256*sizeof(uint32_t), 64>::type data; - }; + const uint32_t* ptr() const { return reinterpret_cast(&data); } - static TD_Table table; - return table.ptr(); - } + private: + std::aligned_storage<256 * sizeof(uint32_t), 64>::type data; + }; -#define AES_T(T, K, V0, V1, V2, V3) \ - (K ^ T[get_byte(0, V0)] ^ \ - rotr< 8>(T[get_byte(1, V1)]) ^ \ - rotr<16>(T[get_byte(2, V2)]) ^ \ - rotr<24>(T[get_byte(3, V3)])) + static TD_Table table; + return table.ptr(); +} + +#define AES_T(T, K, V0, V1, V2, V3) \ + (K ^ T[get_byte(0, V0)] ^ rotr<8>(T[get_byte(1, V1)]) ^ rotr<16>(T[get_byte(2, V2)]) ^ \ + rotr<24>(T[get_byte(3, V3)])) /* -* AES Encryption -*/ -void aes_encrypt_n(const uint8_t in[], uint8_t out[], - size_t blocks, - const secure_vector& EK, - const secure_vector& ME) - { - BOTAN_ASSERT(EK.size() && ME.size() == 16, "Key was set"); + * AES Encryption + */ +void aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, + const secure_vector& EK, const secure_vector& ME) { + BOTAN_ASSERT(EK.size() && ME.size() == 16, "Key was set"); - const size_t cache_line_size = CPUID::cache_line_size(); - const uint32_t* TE = AES_TE(); + const size_t cache_line_size = CPUID::cache_line_size(); + const uint32_t* TE = AES_TE(); - // Hit every cache line of TE - volatile uint32_t Z = 0; - for(size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) - { - Z |= TE[i]; - } - Z &= TE[82]; // this is zero, which hopefully the compiler cannot deduce + // Hit every cache line of TE + volatile uint32_t Z = 0; + for (size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) { + Z |= TE[i]; + } + Z &= TE[82]; // this is zero, which hopefully the compiler cannot deduce - for(size_t i = 0; i < blocks; ++i) - { - uint32_t T0, T1, T2, T3; - load_be(in + 16*i, T0, T1, T2, T3); + for (size_t i = 0; i < blocks; ++i) { + uint32_t T0, T1, T2, T3; + load_be(in + 16 * i, T0, T1, T2, T3); - T0 ^= EK[0]; - T1 ^= EK[1]; - T2 ^= EK[2]; - T3 ^= EK[3]; + T0 ^= EK[0]; + T1 ^= EK[1]; + T2 ^= EK[2]; + T3 ^= EK[3]; - T0 ^= Z; + T0 ^= Z; - uint32_t B0 = AES_T(TE, EK[4], T0, T1, T2, T3); - uint32_t B1 = AES_T(TE, EK[5], T1, T2, T3, T0); - uint32_t B2 = AES_T(TE, EK[6], T2, T3, T0, T1); - uint32_t B3 = AES_T(TE, EK[7], T3, T0, T1, T2); + uint32_t B0 = AES_T(TE, EK[4], T0, T1, T2, T3); + uint32_t B1 = AES_T(TE, EK[5], T1, T2, T3, T0); + uint32_t B2 = AES_T(TE, EK[6], T2, T3, T0, T1); + uint32_t B3 = AES_T(TE, EK[7], T3, T0, T1, T2); - for(size_t r = 2*4; r < EK.size(); r += 2*4) - { - T0 = AES_T(TE, EK[r ], B0, B1, B2, B3); - T1 = AES_T(TE, EK[r+1], B1, B2, B3, B0); - T2 = AES_T(TE, EK[r+2], B2, B3, B0, B1); - T3 = AES_T(TE, EK[r+3], B3, B0, B1, B2); + for (size_t r = 2 * 4; r < EK.size(); r += 2 * 4) { + T0 = AES_T(TE, EK[r], B0, B1, B2, B3); + T1 = AES_T(TE, EK[r + 1], B1, B2, B3, B0); + T2 = AES_T(TE, EK[r + 2], B2, B3, B0, B1); + T3 = AES_T(TE, EK[r + 3], B3, B0, B1, B2); - B0 = AES_T(TE, EK[r+4], T0, T1, T2, T3); - B1 = AES_T(TE, EK[r+5], T1, T2, T3, T0); - B2 = AES_T(TE, EK[r+6], T2, T3, T0, T1); - B3 = AES_T(TE, EK[r+7], T3, T0, T1, T2); - } + B0 = AES_T(TE, EK[r + 4], T0, T1, T2, T3); + B1 = AES_T(TE, EK[r + 5], T1, T2, T3, T0); + B2 = AES_T(TE, EK[r + 6], T2, T3, T0, T1); + B3 = AES_T(TE, EK[r + 7], T3, T0, T1, T2); + } - /* - * Use TE[x] >> 8 instead of SE[] so encryption only references a single - * lookup table. - */ - out[16*i+ 0] = static_cast(TE[get_byte(0, B0)] >> 8) ^ ME[0]; - out[16*i+ 1] = static_cast(TE[get_byte(1, B1)] >> 8) ^ ME[1]; - out[16*i+ 2] = static_cast(TE[get_byte(2, B2)] >> 8) ^ ME[2]; - out[16*i+ 3] = static_cast(TE[get_byte(3, B3)] >> 8) ^ ME[3]; - out[16*i+ 4] = static_cast(TE[get_byte(0, B1)] >> 8) ^ ME[4]; - out[16*i+ 5] = static_cast(TE[get_byte(1, B2)] >> 8) ^ ME[5]; - out[16*i+ 6] = static_cast(TE[get_byte(2, B3)] >> 8) ^ ME[6]; - out[16*i+ 7] = static_cast(TE[get_byte(3, B0)] >> 8) ^ ME[7]; - out[16*i+ 8] = static_cast(TE[get_byte(0, B2)] >> 8) ^ ME[8]; - out[16*i+ 9] = static_cast(TE[get_byte(1, B3)] >> 8) ^ ME[9]; - out[16*i+10] = static_cast(TE[get_byte(2, B0)] >> 8) ^ ME[10]; - out[16*i+11] = static_cast(TE[get_byte(3, B1)] >> 8) ^ ME[11]; - out[16*i+12] = static_cast(TE[get_byte(0, B3)] >> 8) ^ ME[12]; - out[16*i+13] = static_cast(TE[get_byte(1, B0)] >> 8) ^ ME[13]; - out[16*i+14] = static_cast(TE[get_byte(2, B1)] >> 8) ^ ME[14]; - out[16*i+15] = static_cast(TE[get_byte(3, B2)] >> 8) ^ ME[15]; - } - } + /* + * Use TE[x] >> 8 instead of SE[] so encryption only references a single + * lookup table. + */ + out[16 * i + 0] = static_cast(TE[get_byte(0, B0)] >> 8) ^ ME[0]; + out[16 * i + 1] = static_cast(TE[get_byte(1, B1)] >> 8) ^ ME[1]; + out[16 * i + 2] = static_cast(TE[get_byte(2, B2)] >> 8) ^ ME[2]; + out[16 * i + 3] = static_cast(TE[get_byte(3, B3)] >> 8) ^ ME[3]; + out[16 * i + 4] = static_cast(TE[get_byte(0, B1)] >> 8) ^ ME[4]; + out[16 * i + 5] = static_cast(TE[get_byte(1, B2)] >> 8) ^ ME[5]; + out[16 * i + 6] = static_cast(TE[get_byte(2, B3)] >> 8) ^ ME[6]; + out[16 * i + 7] = static_cast(TE[get_byte(3, B0)] >> 8) ^ ME[7]; + out[16 * i + 8] = static_cast(TE[get_byte(0, B2)] >> 8) ^ ME[8]; + out[16 * i + 9] = static_cast(TE[get_byte(1, B3)] >> 8) ^ ME[9]; + out[16 * i + 10] = static_cast(TE[get_byte(2, B0)] >> 8) ^ ME[10]; + out[16 * i + 11] = static_cast(TE[get_byte(3, B1)] >> 8) ^ ME[11]; + out[16 * i + 12] = static_cast(TE[get_byte(0, B3)] >> 8) ^ ME[12]; + out[16 * i + 13] = static_cast(TE[get_byte(1, B0)] >> 8) ^ ME[13]; + out[16 * i + 14] = static_cast(TE[get_byte(2, B1)] >> 8) ^ ME[14]; + out[16 * i + 15] = static_cast(TE[get_byte(3, B2)] >> 8) ^ ME[15]; + } +} /* -* AES Decryption -*/ + * AES Decryption + */ void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, - const secure_vector& DK, - const secure_vector& MD) - { - BOTAN_ASSERT(DK.size() && MD.size() == 16, "Key was set"); + const secure_vector& DK, const secure_vector& MD) { + BOTAN_ASSERT(DK.size() && MD.size() == 16, "Key was set"); - const size_t cache_line_size = CPUID::cache_line_size(); - const uint32_t* TD = AES_TD(); + const size_t cache_line_size = CPUID::cache_line_size(); + const uint32_t* TD = AES_TD(); - volatile uint32_t Z = 0; - for(size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) - { - Z |= TD[i]; - } - for(size_t i = 0; i < 256; i += cache_line_size) - { - Z |= SD[i]; - } - Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce + volatile uint32_t Z = 0; + for (size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) { + Z |= TD[i]; + } + for (size_t i = 0; i < 256; i += cache_line_size) { + Z |= SD[i]; + } + Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce - for(size_t i = 0; i != blocks; ++i) - { - uint32_t T0 = load_be(in, 0) ^ DK[0]; - uint32_t T1 = load_be(in, 1) ^ DK[1]; - uint32_t T2 = load_be(in, 2) ^ DK[2]; - uint32_t T3 = load_be(in, 3) ^ DK[3]; + for (size_t i = 0; i != blocks; ++i) { + uint32_t T0 = load_be(in, 0) ^ DK[0]; + uint32_t T1 = load_be(in, 1) ^ DK[1]; + uint32_t T2 = load_be(in, 2) ^ DK[2]; + uint32_t T3 = load_be(in, 3) ^ DK[3]; - T0 ^= Z; + T0 ^= Z; - uint32_t B0 = AES_T(TD, DK[4], T0, T3, T2, T1); - uint32_t B1 = AES_T(TD, DK[5], T1, T0, T3, T2); - uint32_t B2 = AES_T(TD, DK[6], T2, T1, T0, T3); - uint32_t B3 = AES_T(TD, DK[7], T3, T2, T1, T0); + uint32_t B0 = AES_T(TD, DK[4], T0, T3, T2, T1); + uint32_t B1 = AES_T(TD, DK[5], T1, T0, T3, T2); + uint32_t B2 = AES_T(TD, DK[6], T2, T1, T0, T3); + uint32_t B3 = AES_T(TD, DK[7], T3, T2, T1, T0); - for(size_t r = 2*4; r < DK.size(); r += 2*4) - { - T0 = AES_T(TD, DK[r ], B0, B3, B2, B1); - T1 = AES_T(TD, DK[r+1], B1, B0, B3, B2); - T2 = AES_T(TD, DK[r+2], B2, B1, B0, B3); - T3 = AES_T(TD, DK[r+3], B3, B2, B1, B0); + for (size_t r = 2 * 4; r < DK.size(); r += 2 * 4) { + T0 = AES_T(TD, DK[r], B0, B3, B2, B1); + T1 = AES_T(TD, DK[r + 1], B1, B0, B3, B2); + T2 = AES_T(TD, DK[r + 2], B2, B1, B0, B3); + T3 = AES_T(TD, DK[r + 3], B3, B2, B1, B0); - B0 = AES_T(TD, DK[r+4], T0, T3, T2, T1); - B1 = AES_T(TD, DK[r+5], T1, T0, T3, T2); - B2 = AES_T(TD, DK[r+6], T2, T1, T0, T3); - B3 = AES_T(TD, DK[r+7], T3, T2, T1, T0); - } + B0 = AES_T(TD, DK[r + 4], T0, T3, T2, T1); + B1 = AES_T(TD, DK[r + 5], T1, T0, T3, T2); + B2 = AES_T(TD, DK[r + 6], T2, T1, T0, T3); + B3 = AES_T(TD, DK[r + 7], T3, T2, T1, T0); + } - out[ 0] = SD[get_byte(0, B0)] ^ MD[0]; - out[ 1] = SD[get_byte(1, B3)] ^ MD[1]; - out[ 2] = SD[get_byte(2, B2)] ^ MD[2]; - out[ 3] = SD[get_byte(3, B1)] ^ MD[3]; - out[ 4] = SD[get_byte(0, B1)] ^ MD[4]; - out[ 5] = SD[get_byte(1, B0)] ^ MD[5]; - out[ 6] = SD[get_byte(2, B3)] ^ MD[6]; - out[ 7] = SD[get_byte(3, B2)] ^ MD[7]; - out[ 8] = SD[get_byte(0, B2)] ^ MD[8]; - out[ 9] = SD[get_byte(1, B1)] ^ MD[9]; - out[10] = SD[get_byte(2, B0)] ^ MD[10]; - out[11] = SD[get_byte(3, B3)] ^ MD[11]; - out[12] = SD[get_byte(0, B3)] ^ MD[12]; - out[13] = SD[get_byte(1, B2)] ^ MD[13]; - out[14] = SD[get_byte(2, B1)] ^ MD[14]; - out[15] = SD[get_byte(3, B0)] ^ MD[15]; + out[0] = SD[get_byte(0, B0)] ^ MD[0]; + out[1] = SD[get_byte(1, B3)] ^ MD[1]; + out[2] = SD[get_byte(2, B2)] ^ MD[2]; + out[3] = SD[get_byte(3, B1)] ^ MD[3]; + out[4] = SD[get_byte(0, B1)] ^ MD[4]; + out[5] = SD[get_byte(1, B0)] ^ MD[5]; + out[6] = SD[get_byte(2, B3)] ^ MD[6]; + out[7] = SD[get_byte(3, B2)] ^ MD[7]; + out[8] = SD[get_byte(0, B2)] ^ MD[8]; + out[9] = SD[get_byte(1, B1)] ^ MD[9]; + out[10] = SD[get_byte(2, B0)] ^ MD[10]; + out[11] = SD[get_byte(3, B3)] ^ MD[11]; + out[12] = SD[get_byte(0, B3)] ^ MD[12]; + out[13] = SD[get_byte(1, B2)] ^ MD[13]; + out[14] = SD[get_byte(2, B1)] ^ MD[14]; + out[15] = SD[get_byte(3, B0)] ^ MD[15]; - in += 16; - out += 16; - } - } + in += 16; + out += 16; + } +} -void aes_key_schedule(const uint8_t key[], size_t length, - secure_vector& EK, - secure_vector& DK, - secure_vector& ME, - secure_vector& MD) - { - static const uint32_t RC[10] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, - 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; +void aes_key_schedule(const uint8_t key[], size_t length, secure_vector& EK, + secure_vector& DK, secure_vector& ME, + secure_vector& MD) { + static const uint32_t RC[10] = {0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000}; - const size_t rounds = (length / 4) + 6; + const size_t rounds = (length / 4) + 6; - secure_vector XEK(length + 32), XDK(length + 32); + secure_vector XEK(length + 32), XDK(length + 32); - const size_t X = length / 4; + const size_t X = length / 4; - // Can't happen, but make static analyzers happy - BOTAN_ARG_CHECK(X == 4 || X == 6 || X == 8, "Invalid AES key size"); + // Can't happen, but make static analyzers happy + BOTAN_ARG_CHECK(X == 4 || X == 6 || X == 8, "Invalid AES key size"); - const uint32_t* TD = AES_TD(); + const uint32_t* TD = AES_TD(); - // Prefetch TD and SE which are used later on in this function - volatile uint32_t Z = 0; - const size_t cache_line_size = CPUID::cache_line_size(); + // Prefetch TD and SE which are used later on in this function + volatile uint32_t Z = 0; + const size_t cache_line_size = CPUID::cache_line_size(); - for(size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) - { - Z |= TD[i]; - } - for(size_t i = 0; i < 256; i += cache_line_size) - { - Z |= SE[i]; - } - Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce + for (size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) { + Z |= TD[i]; + } + for (size_t i = 0; i < 256; i += cache_line_size) { + Z |= SE[i]; + } + Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce - for(size_t i = 0; i != X; ++i) - XEK[i] = Z ^ load_be(key, i); + for (size_t i = 0; i != X; ++i) XEK[i] = Z ^ load_be(key, i); - for(size_t i = X; i < 4*(rounds+1); i += X) - { - XEK[i] = XEK[i-X] ^ RC[(i-X)/X] ^ SE_word(rotl<8>(XEK[i-1])); + for (size_t i = X; i < 4 * (rounds + 1); i += X) { + XEK[i] = XEK[i - X] ^ RC[(i - X) / X] ^ SE_word(rotl<8>(XEK[i - 1])); - for(size_t j = 1; j != X; ++j) - { - XEK[i+j] = XEK[i+j-X]; + for (size_t j = 1; j != X; ++j) { + XEK[i + j] = XEK[i + j - X]; - if(X == 8 && j == 4) - XEK[i+j] ^= SE_word(XEK[i+j-1]); - else - XEK[i+j] ^= XEK[i+j-1]; - } - } + if (X == 8 && j == 4) + XEK[i + j] ^= SE_word(XEK[i + j - 1]); + else + XEK[i + j] ^= XEK[i + j - 1]; + } + } - for(size_t i = 0; i != 4*(rounds+1); i += 4) - { - XDK[i ] = XEK[4*rounds-i ]; - XDK[i+1] = XEK[4*rounds-i+1]; - XDK[i+2] = XEK[4*rounds-i+2]; - XDK[i+3] = XEK[4*rounds-i+3]; - } + for (size_t i = 0; i != 4 * (rounds + 1); i += 4) { + XDK[i] = XEK[4 * rounds - i]; + XDK[i + 1] = XEK[4 * rounds - i + 1]; + XDK[i + 2] = XEK[4 * rounds - i + 2]; + XDK[i + 3] = XEK[4 * rounds - i + 3]; + } - for(size_t i = 4; i != length + 24; ++i) - { - XDK[i] = Z ^ SE_word(XDK[i]); - XDK[i] = AES_T(TD, 0, XDK[i], XDK[i], XDK[i], XDK[i]); - } + for (size_t i = 4; i != length + 24; ++i) { + XDK[i] = Z ^ SE_word(XDK[i]); + XDK[i] = AES_T(TD, 0, XDK[i], XDK[i], XDK[i], XDK[i]); + } - ME.resize(16); - MD.resize(16); + ME.resize(16); + MD.resize(16); - for(size_t i = 0; i != 4; ++i) - { - store_be(XEK[i+4*rounds], &ME[4*i]); - store_be(XEK[i], &MD[4*i]); - } + for (size_t i = 0; i != 4; ++i) { + store_be(XEK[i + 4 * rounds], &ME[4 * i]); + store_be(XEK[i], &MD[4 * i]); + } - EK.resize(length + 24); - DK.resize(length + 24); - copy_mem(EK.data(), XEK.data(), EK.size()); - copy_mem(DK.data(), XDK.data(), DK.size()); + EK.resize(length + 24); + DK.resize(length + 24); + copy_mem(EK.data(), XEK.data(), EK.size()); + copy_mem(DK.data(), XDK.data(), DK.size()); #if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - // ARM needs the subkeys to be byte reversed + if (CPUID::has_arm_aes()) { + // ARM needs the subkeys to be byte reversed - for(size_t i = 0; i != EK.size(); ++i) - EK[i] = reverse_bytes(EK[i]); - for(size_t i = 0; i != DK.size(); ++i) - DK[i] = reverse_bytes(DK[i]); - } + for (size_t i = 0; i != EK.size(); ++i) EK[i] = reverse_bytes(EK[i]); + for (size_t i = 0; i != DK.size(); ++i) DK[i] = reverse_bytes(DK[i]); + } #endif - - } +} #undef AES_T -size_t aes_parallelism() - { +size_t aes_parallelism() { #if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return 4; - } + if (CPUID::has_aes_ni()) { + return 4; + } #endif #if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return 4; - } + if (CPUID::has_ppc_crypto()) { + return 4; + } #endif #if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return 4; - } + if (CPUID::has_arm_aes()) { + return 4; + } #endif - return 1; - } + return 1; +} -const char* aes_provider() - { +const char* aes_provider() { #if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return "aesni"; - } + if (CPUID::has_aes_ni()) { + return "aesni"; + } #endif #if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return "power8"; - } + if (CPUID::has_ppc_crypto()) { + return "power8"; + } #endif #if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return "armv8"; - } + if (CPUID::has_arm_aes()) { + return "armv8"; + } #endif #if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return "vperm"; - } + if (CPUID::has_vperm()) { + return "vperm"; + } #endif - return "base"; - } - + return "base"; } +} // namespace + std::string AES_128::provider() const { return aes_provider(); } std::string AES_192::provider() const { return aes_provider(); } std::string AES_256::provider() const { return aes_provider(); } @@ -495,4212 +429,3486 @@ size_t AES_128::parallelism() const { return aes_parallelism(); } size_t AES_192::parallelism() const { return aes_parallelism(); } size_t AES_256::parallelism() const { return aes_parallelism(); } -void AES_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const - { - verify_key_set(m_EK.empty() == false); +void AES_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_EK.empty() == false); #if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_encrypt_n(in, out, blocks); - } + if (CPUID::has_aes_ni()) { + return aesni_encrypt_n(in, out, blocks); + } #endif #if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return armv8_encrypt_n(in, out, blocks); - } + if (CPUID::has_arm_aes()) { + return armv8_encrypt_n(in, out, blocks); + } #endif #if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return power8_encrypt_n(in, out, blocks); - } + if (CPUID::has_ppc_crypto()) { + return power8_encrypt_n(in, out, blocks); + } #endif #if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_encrypt_n(in, out, blocks); - } + if (CPUID::has_vperm()) { + return vperm_encrypt_n(in, out, blocks); + } #endif - aes_encrypt_n(in, out, blocks, m_EK, m_ME); - } - -void AES_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const - { - verify_key_set(m_DK.empty() == false); - -#if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return armv8_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return power8_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_decrypt_n(in, out, blocks); - } -#endif - - aes_decrypt_n(in, out, blocks, m_DK, m_MD); - } - -void AES_128::key_schedule(const uint8_t key[], size_t length) - { -#if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_key_schedule(key, length); - } -#endif - -#if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } -#endif - -#if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } -#endif - -#if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_key_schedule(key, length); - } -#endif - - aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } - -void AES_128::clear() - { - zap(m_EK); - zap(m_DK); - zap(m_ME); - zap(m_MD); - } - -void AES_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const - { - verify_key_set(m_EK.empty() == false); - -#if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_encrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return armv8_encrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return power8_encrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_encrypt_n(in, out, blocks); - } -#endif - - aes_encrypt_n(in, out, blocks, m_EK, m_ME); - } - -void AES_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const - { - verify_key_set(m_DK.empty() == false); - -#if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return armv8_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return power8_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_decrypt_n(in, out, blocks); - } -#endif - - aes_decrypt_n(in, out, blocks, m_DK, m_MD); - } - -void AES_192::key_schedule(const uint8_t key[], size_t length) - { -#if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_key_schedule(key, length); - } -#endif - -#if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } -#endif - -#if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } -#endif - -#if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_key_schedule(key, length); - } -#endif - - aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } - -void AES_192::clear() - { - zap(m_EK); - zap(m_DK); - zap(m_ME); - zap(m_MD); - } - -void AES_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const - { - verify_key_set(m_EK.empty() == false); - -#if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_encrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return armv8_encrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return power8_encrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_encrypt_n(in, out, blocks); - } -#endif - - aes_encrypt_n(in, out, blocks, m_EK, m_ME); - } - -void AES_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const - { - verify_key_set(m_DK.empty() == false); - -#if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return armv8_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return power8_decrypt_n(in, out, blocks); - } -#endif - -#if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_decrypt_n(in, out, blocks); - } -#endif - - aes_decrypt_n(in, out, blocks, m_DK, m_MD); - } - -void AES_256::key_schedule(const uint8_t key[], size_t length) - { -#if defined(BOTAN_HAS_AES_NI) - if(CPUID::has_aes_ni()) - { - return aesni_key_schedule(key, length); - } -#endif - -#if defined(BOTAN_HAS_AES_ARMV8) - if(CPUID::has_arm_aes()) - { - return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } -#endif - -#if defined(BOTAN_HAS_AES_POWER8) - if(CPUID::has_ppc_crypto()) - { - return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } -#endif - -#if defined(BOTAN_HAS_AES_VPERM) - if(CPUID::has_vperm()) - { - return vperm_key_schedule(key, length); - } -#endif - - aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); - } - -void AES_256::clear() - { - zap(m_EK); - zap(m_DK); - zap(m_ME); - zap(m_MD); - } - + aes_encrypt_n(in, out, blocks, m_EK, m_ME); } -/* -* Algorithm Identifier -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +void AES_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_DK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if (CPUID::has_aes_ni()) { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if (CPUID::has_arm_aes()) { + return armv8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if (CPUID::has_ppc_crypto()) { + return power8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_VPERM) + if (CPUID::has_vperm()) { + return vperm_decrypt_n(in, out, blocks); + } +#endif + + aes_decrypt_n(in, out, blocks, m_DK, m_MD); +} + +void AES_128::key_schedule(const uint8_t key[], size_t length) { +#if defined(BOTAN_HAS_AES_NI) + if (CPUID::has_aes_ni()) { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if (CPUID::has_arm_aes()) { + return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if (CPUID::has_ppc_crypto()) { + return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } +#endif + +#if defined(BOTAN_HAS_AES_VPERM) + if (CPUID::has_vperm()) { + return vperm_key_schedule(key, length); + } +#endif + + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); +} + +void AES_128::clear() { + zap(m_EK); + zap(m_DK); + zap(m_ME); + zap(m_MD); +} + +void AES_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_EK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if (CPUID::has_aes_ni()) { + return aesni_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if (CPUID::has_arm_aes()) { + return armv8_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if (CPUID::has_ppc_crypto()) { + return power8_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_VPERM) + if (CPUID::has_vperm()) { + return vperm_encrypt_n(in, out, blocks); + } +#endif + + aes_encrypt_n(in, out, blocks, m_EK, m_ME); +} + +void AES_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_DK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if (CPUID::has_aes_ni()) { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if (CPUID::has_arm_aes()) { + return armv8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if (CPUID::has_ppc_crypto()) { + return power8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_VPERM) + if (CPUID::has_vperm()) { + return vperm_decrypt_n(in, out, blocks); + } +#endif + + aes_decrypt_n(in, out, blocks, m_DK, m_MD); +} + +void AES_192::key_schedule(const uint8_t key[], size_t length) { +#if defined(BOTAN_HAS_AES_NI) + if (CPUID::has_aes_ni()) { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if (CPUID::has_arm_aes()) { + return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if (CPUID::has_ppc_crypto()) { + return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } +#endif + +#if defined(BOTAN_HAS_AES_VPERM) + if (CPUID::has_vperm()) { + return vperm_key_schedule(key, length); + } +#endif + + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); +} + +void AES_192::clear() { + zap(m_EK); + zap(m_DK); + zap(m_ME); + zap(m_MD); +} + +void AES_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_EK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if (CPUID::has_aes_ni()) { + return aesni_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if (CPUID::has_arm_aes()) { + return armv8_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if (CPUID::has_ppc_crypto()) { + return power8_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_VPERM) + if (CPUID::has_vperm()) { + return vperm_encrypt_n(in, out, blocks); + } +#endif + + aes_encrypt_n(in, out, blocks, m_EK, m_ME); +} + +void AES_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_DK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if (CPUID::has_aes_ni()) { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if (CPUID::has_arm_aes()) { + return armv8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if (CPUID::has_ppc_crypto()) { + return power8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_VPERM) + if (CPUID::has_vperm()) { + return vperm_decrypt_n(in, out, blocks); + } +#endif + + aes_decrypt_n(in, out, blocks, m_DK, m_MD); +} + +void AES_256::key_schedule(const uint8_t key[], size_t length) { +#if defined(BOTAN_HAS_AES_NI) + if (CPUID::has_aes_ni()) { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if (CPUID::has_arm_aes()) { + return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if (CPUID::has_ppc_crypto()) { + return aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } +#endif + +#if defined(BOTAN_HAS_AES_VPERM) + if (CPUID::has_vperm()) { + return vperm_key_schedule(key, length); + } +#endif + + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); +} + +void AES_256::clear() { + zap(m_EK); + zap(m_DK); + zap(m_ME); + zap(m_MD); +} + +} // namespace Botan +/* + * Algorithm Identifier + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Create an AlgorithmIdentifier -*/ -AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, - const std::vector& param) : - oid(alg_id), - parameters(param) - {} + * Create an AlgorithmIdentifier + */ +AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, const std::vector& param) + : oid(alg_id), parameters(param) {} /* -* Create an AlgorithmIdentifier -*/ + * Create an AlgorithmIdentifier + */ AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, - const std::vector& param) : - AlgorithmIdentifier(OID::from_string(alg_id), param) - {} + const std::vector& param) + : AlgorithmIdentifier(OID::from_string(alg_id), param) {} /* -* Create an AlgorithmIdentifier -*/ -AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, - Encoding_Option option) : - oid(alg_id), - parameters() - { - const uint8_t DER_NULL[] = { 0x05, 0x00 }; + * Create an AlgorithmIdentifier + */ +AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, Encoding_Option option) + : oid(alg_id), parameters() { + const uint8_t DER_NULL[] = {0x05, 0x00}; - if(option == USE_NULL_PARAM) - parameters.assign(DER_NULL, DER_NULL + 2); - } + if (option == USE_NULL_PARAM) parameters.assign(DER_NULL, DER_NULL + 2); +} /* -* Create an AlgorithmIdentifier -*/ -AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, - Encoding_Option option) : - oid(OID::from_string(alg_id)), - parameters() - { - const uint8_t DER_NULL[] = { 0x05, 0x00 }; + * Create an AlgorithmIdentifier + */ +AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, Encoding_Option option) + : oid(OID::from_string(alg_id)), parameters() { + const uint8_t DER_NULL[] = {0x05, 0x00}; - if(option == USE_NULL_PARAM) - parameters.assign(DER_NULL, DER_NULL + 2); - } + if (option == USE_NULL_PARAM) parameters.assign(DER_NULL, DER_NULL + 2); +} /* -* Compare two AlgorithmIdentifiers -*/ + * Compare two AlgorithmIdentifiers + */ namespace { -bool param_null_or_empty(const std::vector& p) - { - if(p.size() == 2 && (p[0] == 0x05) && (p[1] == 0x00)) - return true; - return p.empty(); - } - +bool param_null_or_empty(const std::vector& p) { + if (p.size() == 2 && (p[0] == 0x05) && (p[1] == 0x00)) return true; + return p.empty(); } -bool operator==(const AlgorithmIdentifier& a1, const AlgorithmIdentifier& a2) - { - if(a1.get_oid() != a2.get_oid()) - return false; +} // namespace - if(param_null_or_empty(a1.get_parameters()) && - param_null_or_empty(a2.get_parameters())) - return true; +bool operator==(const AlgorithmIdentifier& a1, const AlgorithmIdentifier& a2) { + if (a1.get_oid() != a2.get_oid()) return false; - return (a1.get_parameters() == a2.get_parameters()); - } - -/* -* Compare two AlgorithmIdentifiers -*/ -bool operator!=(const AlgorithmIdentifier& a1, const AlgorithmIdentifier& a2) - { - return !(a1 == a2); - } - -/* -* DER encode an AlgorithmIdentifier -*/ -void AlgorithmIdentifier::encode_into(DER_Encoder& codec) const - { - codec.start_cons(SEQUENCE) - .encode(get_oid()) - .raw_bytes(get_parameters()) - .end_cons(); - } - -/* -* Decode a BER encoded AlgorithmIdentifier -*/ -void AlgorithmIdentifier::decode_from(BER_Decoder& codec) - { - codec.start_cons(SEQUENCE) - .decode(oid) - .raw_bytes(parameters) - .end_cons(); - } + if (param_null_or_empty(a1.get_parameters()) && param_null_or_empty(a2.get_parameters())) + return true; + return (a1.get_parameters() == a2.get_parameters()); } -/* -* Attribute -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Compare two AlgorithmIdentifiers + */ +bool operator!=(const AlgorithmIdentifier& a1, const AlgorithmIdentifier& a2) { + return !(a1 == a2); +} + +/* + * DER encode an AlgorithmIdentifier + */ +void AlgorithmIdentifier::encode_into(DER_Encoder& codec) const { + codec.start_cons(SEQUENCE).encode(get_oid()).raw_bytes(get_parameters()).end_cons(); +} + +/* + * Decode a BER encoded AlgorithmIdentifier + */ +void AlgorithmIdentifier::decode_from(BER_Decoder& codec) { + codec.start_cons(SEQUENCE).decode(oid).raw_bytes(parameters).end_cons(); +} + +} // namespace Botan +/* + * Attribute + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Create an Attribute -*/ -Attribute::Attribute(const OID& attr_oid, const std::vector& attr_value) : - oid(attr_oid), - parameters(attr_value) - {} + * Create an Attribute + */ +Attribute::Attribute(const OID& attr_oid, const std::vector& attr_value) + : oid(attr_oid), parameters(attr_value) {} /* -* Create an Attribute -*/ -Attribute::Attribute(const std::string& attr_oid, - const std::vector& attr_value) : - oid(OID::from_string(attr_oid)), - parameters(attr_value) - {} + * Create an Attribute + */ +Attribute::Attribute(const std::string& attr_oid, const std::vector& attr_value) + : oid(OID::from_string(attr_oid)), parameters(attr_value) {} /* -* DER encode a Attribute -*/ -void Attribute::encode_into(DER_Encoder& codec) const - { - codec.start_cons(SEQUENCE) - .encode(oid) - .start_cons(SET) - .raw_bytes(parameters) - .end_cons() - .end_cons(); - } - -/* -* Decode a BER encoded Attribute -*/ -void Attribute::decode_from(BER_Decoder& codec) - { - codec.start_cons(SEQUENCE) - .decode(oid) - .start_cons(SET) - .raw_bytes(parameters) - .end_cons() - .end_cons(); - } - + * DER encode a Attribute + */ +void Attribute::encode_into(DER_Encoder& codec) const { + codec.start_cons(SEQUENCE) + .encode(oid) + .start_cons(SET) + .raw_bytes(parameters) + .end_cons() + .end_cons(); } + /* -* ASN.1 Internals -* (C) 1999-2007,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Decode a BER encoded Attribute + */ +void Attribute::decode_from(BER_Decoder& codec) { + codec.start_cons(SEQUENCE) + .decode(oid) + .start_cons(SET) + .raw_bytes(parameters) + .end_cons() + .end_cons(); +} + +} // namespace Botan +/* + * ASN.1 Internals + * (C) 1999-2007,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #include namespace Botan { -std::vector ASN1_Object::BER_encode() const - { - std::vector output; - DER_Encoder der(output); - this->encode_into(der); - return output; - } +std::vector ASN1_Object::BER_encode() const { + std::vector output; + DER_Encoder der(output); + this->encode_into(der); + return output; +} /* -* Check a type invariant on BER data -*/ + * Check a type invariant on BER data + */ void BER_Object::assert_is_a(ASN1_Tag type_tag_, ASN1_Tag class_tag_, - const std::string& descr) const - { - if(this->is_a(type_tag_, class_tag_) == false) - { - std::stringstream msg; + const std::string& descr) const { + if (this->is_a(type_tag_, class_tag_) == false) { + std::stringstream msg; - msg << "Tag mismatch when decoding " << descr << " got "; + msg << "Tag mismatch when decoding " << descr << " got "; - if(class_tag == NO_OBJECT && type_tag == NO_OBJECT) - { - msg << "EOF"; - } - else - { - if(class_tag == UNIVERSAL || class_tag == CONSTRUCTED) - { - msg << asn1_tag_to_string(type_tag); - } - else - { - msg << std::to_string(type_tag); + if (class_tag == NO_OBJECT && type_tag == NO_OBJECT) { + msg << "EOF"; + } else { + if (class_tag == UNIVERSAL || class_tag == CONSTRUCTED) { + msg << asn1_tag_to_string(type_tag); + } else { + msg << std::to_string(type_tag); } - msg << "/" << asn1_class_to_string(class_tag); - } + msg << "/" << asn1_class_to_string(class_tag); + } - msg << " expected "; + msg << " expected "; - if(class_tag_ == UNIVERSAL || class_tag_ == CONSTRUCTED) - { - msg << asn1_tag_to_string(type_tag_); - } - else - { - msg << std::to_string(type_tag_); - } + if (class_tag_ == UNIVERSAL || class_tag_ == CONSTRUCTED) { + msg << asn1_tag_to_string(type_tag_); + } else { + msg << std::to_string(type_tag_); + } - msg << "/" << asn1_class_to_string(class_tag_); + msg << "/" << asn1_class_to_string(class_tag_); - throw BER_Decoding_Error(msg.str()); - } - } + throw BER_Decoding_Error(msg.str()); + } +} -bool BER_Object::is_a(ASN1_Tag type_tag_, ASN1_Tag class_tag_) const - { - return (type_tag == type_tag_ && class_tag == class_tag_); - } +bool BER_Object::is_a(ASN1_Tag type_tag_, ASN1_Tag class_tag_) const { + return (type_tag == type_tag_ && class_tag == class_tag_); +} -bool BER_Object::is_a(int type_tag_, ASN1_Tag class_tag_) const - { - return is_a(ASN1_Tag(type_tag_), class_tag_); - } +bool BER_Object::is_a(int type_tag_, ASN1_Tag class_tag_) const { + return is_a(ASN1_Tag(type_tag_), class_tag_); +} -void BER_Object::set_tagging(ASN1_Tag t, ASN1_Tag c) - { - type_tag = t; - class_tag = c; - } +void BER_Object::set_tagging(ASN1_Tag t, ASN1_Tag c) { + type_tag = t; + class_tag = c; +} -std::string asn1_class_to_string(ASN1_Tag type) - { - switch(type) - { - case UNIVERSAL: - return "UNIVERSAL"; - case CONSTRUCTED: - return "CONSTRUCTED"; - case CONTEXT_SPECIFIC: - return "CONTEXT_SPECIFIC"; - case APPLICATION: - return "APPLICATION"; - case CONSTRUCTED | CONTEXT_SPECIFIC: - return "PRIVATE"; - case Botan::NO_OBJECT: - return "NO_OBJECT"; - default: - return "CLASS(" + std::to_string(static_cast(type)) + ")"; - } - } +std::string asn1_class_to_string(ASN1_Tag type) { + switch (type) { + case UNIVERSAL: + return "UNIVERSAL"; + case CONSTRUCTED: + return "CONSTRUCTED"; + case CONTEXT_SPECIFIC: + return "CONTEXT_SPECIFIC"; + case APPLICATION: + return "APPLICATION"; + case CONSTRUCTED | CONTEXT_SPECIFIC: + return "PRIVATE"; + case Botan::NO_OBJECT: + return "NO_OBJECT"; + default: + return "CLASS(" + std::to_string(static_cast(type)) + ")"; + } +} -std::string asn1_tag_to_string(ASN1_Tag type) - { - switch(type) - { - case Botan::SEQUENCE: - return "SEQUENCE"; +std::string asn1_tag_to_string(ASN1_Tag type) { + switch (type) { + case Botan::SEQUENCE: + return "SEQUENCE"; - case Botan::SET: - return "SET"; + case Botan::SET: + return "SET"; - case Botan::PRINTABLE_STRING: - return "PRINTABLE STRING"; + case Botan::PRINTABLE_STRING: + return "PRINTABLE STRING"; - case Botan::NUMERIC_STRING: - return "NUMERIC STRING"; + case Botan::NUMERIC_STRING: + return "NUMERIC STRING"; - case Botan::IA5_STRING: - return "IA5 STRING"; + case Botan::IA5_STRING: + return "IA5 STRING"; - case Botan::T61_STRING: - return "T61 STRING"; + case Botan::T61_STRING: + return "T61 STRING"; - case Botan::UTF8_STRING: - return "UTF8 STRING"; + case Botan::UTF8_STRING: + return "UTF8 STRING"; - case Botan::VISIBLE_STRING: - return "VISIBLE STRING"; + case Botan::VISIBLE_STRING: + return "VISIBLE STRING"; - case Botan::BMP_STRING: - return "BMP STRING"; + case Botan::BMP_STRING: + return "BMP STRING"; - case Botan::UNIVERSAL_STRING: - return "UNIVERSAL STRING"; + case Botan::UNIVERSAL_STRING: + return "UNIVERSAL STRING"; - case Botan::UTC_TIME: - return "UTC TIME"; + case Botan::UTC_TIME: + return "UTC TIME"; - case Botan::GENERALIZED_TIME: - return "GENERALIZED TIME"; + case Botan::GENERALIZED_TIME: + return "GENERALIZED TIME"; - case Botan::OCTET_STRING: - return "OCTET STRING"; + case Botan::OCTET_STRING: + return "OCTET STRING"; - case Botan::BIT_STRING: - return "BIT STRING"; + case Botan::BIT_STRING: + return "BIT STRING"; - case Botan::ENUMERATED: - return "ENUMERATED"; + case Botan::ENUMERATED: + return "ENUMERATED"; - case Botan::INTEGER: - return "INTEGER"; + case Botan::INTEGER: + return "INTEGER"; - case Botan::NULL_TAG: - return "NULL"; + case Botan::NULL_TAG: + return "NULL"; - case Botan::OBJECT_ID: - return "OBJECT"; + case Botan::OBJECT_ID: + return "OBJECT"; - case Botan::BOOLEAN: - return "BOOLEAN"; + case Botan::BOOLEAN: + return "BOOLEAN"; - case Botan::NO_OBJECT: - return "NO_OBJECT"; + case Botan::NO_OBJECT: + return "NO_OBJECT"; - default: - return "TAG(" + std::to_string(static_cast(type)) + ")"; - } - } + default: + return "TAG(" + std::to_string(static_cast(type)) + ")"; + } +} /* -* BER Decoding Exceptions -*/ -BER_Decoding_Error::BER_Decoding_Error(const std::string& str) : - Decoding_Error("BER: " + str) {} + * BER Decoding Exceptions + */ +BER_Decoding_Error::BER_Decoding_Error(const std::string& str) : Decoding_Error("BER: " + str) {} -BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag) : - BER_Decoding_Error(str + ": " + std::to_string(tag)) {} +BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag) + : BER_Decoding_Error(str + ": " + std::to_string(tag)) {} -BER_Bad_Tag::BER_Bad_Tag(const std::string& str, - ASN1_Tag tag1, ASN1_Tag tag2) : - BER_Decoding_Error(str + ": " + std::to_string(tag1) + "/" + std::to_string(tag2)) {} +BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag1, ASN1_Tag tag2) + : BER_Decoding_Error(str + ": " + std::to_string(tag1) + "/" + std::to_string(tag2)) {} namespace ASN1 { /* -* Put some arbitrary bytes into a SEQUENCE -*/ -std::vector put_in_sequence(const std::vector& contents) - { - return ASN1::put_in_sequence(contents.data(), contents.size()); - } - -std::vector put_in_sequence(const uint8_t bits[], size_t len) - { - std::vector output; - DER_Encoder(output) - .start_cons(SEQUENCE) - .raw_bytes(bits, len) - .end_cons(); - return output; - } - -/* -* Convert a BER object into a string object -*/ -std::string to_string(const BER_Object& obj) - { - return std::string(cast_uint8_ptr_to_char(obj.bits()), - obj.length()); - } - -/* -* Do heuristic tests for BER data -*/ -bool maybe_BER(DataSource& source) - { - uint8_t first_u8; - if(!source.peek_byte(first_u8)) - { - BOTAN_ASSERT_EQUAL(source.read_byte(first_u8), 0, "Expected EOF"); - throw Stream_IO_Error("ASN1::maybe_BER: Source was empty"); - } - - if(first_u8 == (SEQUENCE | CONSTRUCTED)) - return true; - return false; - } - + * Put some arbitrary bytes into a SEQUENCE + */ +std::vector put_in_sequence(const std::vector& contents) { + return ASN1::put_in_sequence(contents.data(), contents.size()); } +std::vector put_in_sequence(const uint8_t bits[], size_t len) { + std::vector output; + DER_Encoder(output).start_cons(SEQUENCE).raw_bytes(bits, len).end_cons(); + return output; } -/* -* ASN.1 OID -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Convert a BER object into a string object + */ +std::string to_string(const BER_Object& obj) { + return std::string(cast_uint8_ptr_to_char(obj.bits()), obj.length()); +} + +/* + * Do heuristic tests for BER data + */ +bool maybe_BER(DataSource& source) { + uint8_t first_u8; + if (!source.peek_byte(first_u8)) { + BOTAN_ASSERT_EQUAL(source.read_byte(first_u8), 0, "Expected EOF"); + throw Stream_IO_Error("ASN1::maybe_BER: Source was empty"); + } + + if (first_u8 == (SEQUENCE | CONSTRUCTED)) return true; + return false; +} + +} // namespace ASN1 + +} // namespace Botan +/* + * ASN.1 OID + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { // returns empty on invalid -std::vector parse_oid_str(const std::string& oid) - { - try - { - std::string elem; - std::vector oid_elems; +std::vector parse_oid_str(const std::string& oid) { + try { + std::string elem; + std::vector oid_elems; - for(char c : oid) - { - if(c == '.') - { - if(elem.empty()) - return std::vector(); - oid_elems.push_back(to_u32bit(elem)); - elem.clear(); + for (char c : oid) { + if (c == '.') { + if (elem.empty()) return std::vector(); + oid_elems.push_back(to_u32bit(elem)); + elem.clear(); + } else { + elem += c; } - else - { - elem += c; - } - } + } - if(elem.empty()) - return std::vector(); - oid_elems.push_back(to_u32bit(elem)); + if (elem.empty()) return std::vector(); + oid_elems.push_back(to_u32bit(elem)); - if(oid_elems.size() < 2) - return std::vector(); - - return oid_elems; - } - catch(Invalid_Argument&) // thrown by to_u32bit - { - return std::vector(); - } - } + if (oid_elems.size() < 2) return std::vector(); + return oid_elems; + } catch (Invalid_Argument&) // thrown by to_u32bit + { + return std::vector(); + } } -//static -OID OID::from_string(const std::string& str) - { - if(str.empty()) - throw Invalid_Argument("OID::from_string argument must be non-empty"); +} // namespace - const OID o = OIDS::str2oid_or_empty(str); - if(o.has_value()) - return o; +// static +OID OID::from_string(const std::string& str) { + if (str.empty()) throw Invalid_Argument("OID::from_string argument must be non-empty"); - std::vector raw = parse_oid_str(str); + const OID o = OIDS::str2oid_or_empty(str); + if (o.has_value()) return o; - if(raw.size() > 0) - return OID(std::move(raw)); + std::vector raw = parse_oid_str(str); - throw Lookup_Error("No OID associated with name " + str); - } - -/* -* ASN.1 OID Constructor -*/ -OID::OID(const std::string& oid_str) - { - if(!oid_str.empty()) - { - m_id = parse_oid_str(oid_str); - - if(m_id.size() < 2 || m_id[0] > 2) - throw Invalid_OID(oid_str); - if((m_id[0] == 0 || m_id[0] == 1) && m_id[1] > 39) - throw Invalid_OID(oid_str); - } - } - -/* -* Return this OID as a string -*/ -std::string OID::to_string() const - { - std::ostringstream oss; - for(size_t i = 0; i != m_id.size(); ++i) - { - oss << m_id[i]; - if(i != m_id.size() - 1) - oss << "."; - } - return oss.str(); - } - -std::string OID::to_formatted_string() const - { - const std::string s = OIDS::oid2str_or_empty(*this); - if(!s.empty()) - return s; - return this->to_string(); - } - -/* -* Append another component to the OID -*/ -OID operator+(const OID& oid, uint32_t new_component) - { - std::vector val = oid.get_components(); - val.push_back(new_component); - return OID(std::move(val)); - } - -/* -* Compare two OIDs -*/ -bool operator<(const OID& a, const OID& b) - { - const std::vector& oid1 = a.get_components(); - const std::vector& oid2 = b.get_components(); - - return std::lexicographical_compare(oid1.begin(), oid1.end(), - oid2.begin(), oid2.end()); - } - -/* -* DER encode an OBJECT IDENTIFIER -*/ -void OID::encode_into(DER_Encoder& der) const - { - if(m_id.size() < 2) - throw Invalid_Argument("OID::encode_into: OID is invalid"); - - std::vector encoding; - - if(m_id[0] > 2 || m_id[1] >= 40) - throw Encoding_Error("Invalid OID prefix, cannot encode"); - - encoding.push_back(static_cast(40 * m_id[0] + m_id[1])); - - for(size_t i = 2; i != m_id.size(); ++i) - { - if(m_id[i] == 0) - encoding.push_back(0); - else - { - size_t blocks = high_bit(m_id[i]) + 6; - blocks = (blocks - (blocks % 7)) / 7; - - BOTAN_ASSERT(blocks > 0, "Math works"); - - for(size_t j = 0; j != blocks - 1; ++j) - encoding.push_back(0x80 | ((m_id[i] >> 7*(blocks-j-1)) & 0x7F)); - encoding.push_back(m_id[i] & 0x7F); - } - } - der.add_object(OBJECT_ID, UNIVERSAL, encoding); - } - -/* -* Decode a BER encoded OBJECT IDENTIFIER -*/ -void OID::decode_from(BER_Decoder& decoder) - { - BER_Object obj = decoder.get_next_object(); - if(obj.tagging() != OBJECT_ID) - throw BER_Bad_Tag("Error decoding OID, unknown tag", obj.tagging()); - - const size_t length = obj.length(); - const uint8_t* bits = obj.bits(); - - if(length < 2 && !(length == 1 && bits[0] == 0)) - { - throw BER_Decoding_Error("OID encoding is too short"); - } - - m_id.clear(); - m_id.push_back(bits[0] / 40); - m_id.push_back(bits[0] % 40); - - size_t i = 0; - while(i != length - 1) - { - uint32_t component = 0; - while(i != length - 1) - { - ++i; - - if(component >> (32-7)) - throw Decoding_Error("OID component overflow"); - - component = (component << 7) + (bits[i] & 0x7F); - - if(!(bits[i] & 0x80)) - break; - } - m_id.push_back(component); - } - } + if (raw.size() > 0) return OID(std::move(raw)); + throw Lookup_Error("No OID associated with name " + str); } -/* -* (C) 2014,2015,2017 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ -#include +/* + * ASN.1 OID Constructor + */ +OID::OID(const std::string& oid_str) { + if (!oid_str.empty()) { + m_id = parse_oid_str(oid_str); + + if (m_id.size() < 2 || m_id[0] > 2) throw Invalid_OID(oid_str); + if ((m_id[0] == 0 || m_id[0] == 1) && m_id[1] > 39) throw Invalid_OID(oid_str); + } +} + +/* + * Return this OID as a string + */ +std::string OID::to_string() const { + std::ostringstream oss; + for (size_t i = 0; i != m_id.size(); ++i) { + oss << m_id[i]; + if (i != m_id.size() - 1) oss << "."; + } + return oss.str(); +} + +std::string OID::to_formatted_string() const { + const std::string s = OIDS::oid2str_or_empty(*this); + if (!s.empty()) return s; + return this->to_string(); +} + +/* + * Append another component to the OID + */ +OID operator+(const OID& oid, uint32_t new_component) { + std::vector val = oid.get_components(); + val.push_back(new_component); + return OID(std::move(val)); +} + +/* + * Compare two OIDs + */ +bool operator<(const OID& a, const OID& b) { + const std::vector& oid1 = a.get_components(); + const std::vector& oid2 = b.get_components(); + + return std::lexicographical_compare(oid1.begin(), oid1.end(), oid2.begin(), oid2.end()); +} + +/* + * DER encode an OBJECT IDENTIFIER + */ +void OID::encode_into(DER_Encoder& der) const { + if (m_id.size() < 2) throw Invalid_Argument("OID::encode_into: OID is invalid"); + + std::vector encoding; + + if (m_id[0] > 2 || m_id[1] >= 40) throw Encoding_Error("Invalid OID prefix, cannot encode"); + + encoding.push_back(static_cast(40 * m_id[0] + m_id[1])); + + for (size_t i = 2; i != m_id.size(); ++i) { + if (m_id[i] == 0) + encoding.push_back(0); + else { + size_t blocks = high_bit(m_id[i]) + 6; + blocks = (blocks - (blocks % 7)) / 7; + + BOTAN_ASSERT(blocks > 0, "Math works"); + + for (size_t j = 0; j != blocks - 1; ++j) + encoding.push_back(0x80 | ((m_id[i] >> 7 * (blocks - j - 1)) & 0x7F)); + encoding.push_back(m_id[i] & 0x7F); + } + } + der.add_object(OBJECT_ID, UNIVERSAL, encoding); +} + +/* + * Decode a BER encoded OBJECT IDENTIFIER + */ +void OID::decode_from(BER_Decoder& decoder) { + BER_Object obj = decoder.get_next_object(); + if (obj.tagging() != OBJECT_ID) + throw BER_Bad_Tag("Error decoding OID, unknown tag", obj.tagging()); + + const size_t length = obj.length(); + const uint8_t* bits = obj.bits(); + + if (length < 2 && !(length == 1 && bits[0] == 0)) { + throw BER_Decoding_Error("OID encoding is too short"); + } + + m_id.clear(); + m_id.push_back(bits[0] / 40); + m_id.push_back(bits[0] % 40); + + size_t i = 0; + while (i != length - 1) { + uint32_t component = 0; + while (i != length - 1) { + ++i; + + if (component >> (32 - 7)) throw Decoding_Error("OID component overflow"); + + component = (component << 7) + (bits[i] & 0x7F); + + if (!(bits[i] & 0x80)) break; + } + m_id.push_back(component); + } +} + +} // namespace Botan +/* + * (C) 2014,2015,2017 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + #include +#include namespace Botan { namespace { -bool all_printable_chars(const uint8_t bits[], size_t bits_len) - { - for(size_t i = 0; i != bits_len; ++i) - { - int c = bits[i]; - if(c > 127) - return false; - - if((std::isalnum(c) || c == '.' || c == ':' || c == '/' || c == '-') == false) - return false; - } - return true; - } - -/* -* Special hack to handle GeneralName [2] and [6] (DNS name and URI) -*/ -bool possibly_a_general_name(const uint8_t bits[], size_t bits_len) - { - if(bits_len <= 2) - return false; - - if(bits[0] != 0x82 && bits[0] != 0x86) - return false; - - if(bits[1] != bits_len - 2) - return false; - - if(all_printable_chars(bits + 2, bits_len - 2) == false) - return false; - - return true; - } +bool all_printable_chars(const uint8_t bits[], size_t bits_len) { + for (size_t i = 0; i != bits_len; ++i) { + int c = bits[i]; + if (c > 127) return false; + if ((std::isalnum(c) || c == '.' || c == ':' || c == '/' || c == '-') == false) + return false; + } + return true; } -std::string ASN1_Formatter::print(const uint8_t in[], size_t len) const - { - std::ostringstream output; - print_to_stream(output, in, len); - return output.str(); - } +/* + * Special hack to handle GeneralName [2] and [6] (DNS name and URI) + */ +bool possibly_a_general_name(const uint8_t bits[], size_t bits_len) { + if (bits_len <= 2) return false; -void ASN1_Formatter::print_to_stream(std::ostream& output, - const uint8_t in[], - size_t len) const - { - BER_Decoder dec(in, len); - decode(output, dec, 0); - } + if (bits[0] != 0x82 && bits[0] != 0x86) return false; -void ASN1_Formatter::decode(std::ostream& output, - BER_Decoder& decoder, - size_t level) const - { - BER_Object obj = decoder.get_next_object(); + if (bits[1] != bits_len - 2) return false; - const bool recurse_deeper = (m_max_depth == 0 || level < m_max_depth); + if (all_printable_chars(bits + 2, bits_len - 2) == false) return false; - while(obj.is_set()) - { - const ASN1_Tag type_tag = obj.type(); - const ASN1_Tag class_tag = obj.get_class(); - const size_t length = obj.length(); + return true; +} - /* hack to insert the tag+length back in front of the stuff now - that we've gotten the type info */ - std::vector bits; - DER_Encoder(bits).add_object(type_tag, class_tag, obj.bits(), obj.length()); +} // namespace - BER_Decoder data(bits); +std::string ASN1_Formatter::print(const uint8_t in[], size_t len) const { + std::ostringstream output; + print_to_stream(output, in, len); + return output.str(); +} - if(class_tag & CONSTRUCTED) - { - BER_Decoder cons_info(obj.bits(), obj.length()); +void ASN1_Formatter::print_to_stream(std::ostream& output, const uint8_t in[], size_t len) const { + BER_Decoder dec(in, len); + decode(output, dec, 0); +} - if(recurse_deeper) - { +void ASN1_Formatter::decode(std::ostream& output, BER_Decoder& decoder, size_t level) const { + BER_Object obj = decoder.get_next_object(); + + const bool recurse_deeper = (m_max_depth == 0 || level < m_max_depth); + + while (obj.is_set()) { + const ASN1_Tag type_tag = obj.type(); + const ASN1_Tag class_tag = obj.get_class(); + const size_t length = obj.length(); + + /* hack to insert the tag+length back in front of the stuff now + that we've gotten the type info */ + std::vector bits; + DER_Encoder(bits).add_object(type_tag, class_tag, obj.bits(), obj.length()); + + BER_Decoder data(bits); + + if (class_tag & CONSTRUCTED) { + BER_Decoder cons_info(obj.bits(), obj.length()); + + if (recurse_deeper) { + output << format(type_tag, class_tag, level, length, ""); + decode(output, cons_info, level + 1); // recurse + } else { + output << format(type_tag, class_tag, level, length, + format_bin(type_tag, class_tag, bits)); + } + } else if ((class_tag & APPLICATION) || (class_tag & CONTEXT_SPECIFIC)) { + bool success_parsing_cs = false; + + if (m_print_context_specific) { + try { + if (possibly_a_general_name(bits.data(), bits.size())) { + output << format( + type_tag, class_tag, level, level, + std::string(cast_uint8_ptr_to_char(&bits[2]), bits.size() - 2)); + success_parsing_cs = true; + } else if (recurse_deeper) { + std::vector inner_bits; + data.decode(inner_bits, type_tag); + + BER_Decoder inner(inner_bits); + std::ostringstream inner_data; + decode(inner_data, inner, level + 1); // recurse + output << inner_data.str(); + success_parsing_cs = true; + } + } catch (...) { + } + } + + if (success_parsing_cs == false) { + output << format(type_tag, class_tag, level, length, + format_bin(type_tag, class_tag, bits)); + } + } else if (type_tag == OBJECT_ID) { + OID oid; + data.decode(oid); + + std::string out = OIDS::oid2str_or_empty(oid); + if (out.empty()) { + out = oid.to_string(); + } else { + out += " [" + oid.to_string() + "]"; + } + + output << format(type_tag, class_tag, level, length, out); + } else if (type_tag == INTEGER || type_tag == ENUMERATED) { + BigInt number; + + if (type_tag == INTEGER) { + data.decode(number); + } else if (type_tag == ENUMERATED) { + data.decode(number, ENUMERATED, class_tag); + } + + std::vector rep = BigInt::encode(number); + if (rep.empty()) // if zero + rep.resize(1); + + output << format(type_tag, class_tag, level, length, hex_encode(rep)); + } else if (type_tag == BOOLEAN) { + bool boolean; + data.decode(boolean); + output << format(type_tag, class_tag, level, length, (boolean ? "true" : "false")); + } else if (type_tag == NULL_TAG) { output << format(type_tag, class_tag, level, length, ""); - decode(output, cons_info, level + 1); // recurse - } - else - { - output << format(type_tag, class_tag, level, length, - format_bin(type_tag, class_tag, bits)); - } - } - else if((class_tag & APPLICATION) || (class_tag & CONTEXT_SPECIFIC)) - { - bool success_parsing_cs = false; + } else if (type_tag == OCTET_STRING || type_tag == BIT_STRING) { + std::vector decoded_bits; + data.decode(decoded_bits, type_tag); + bool printing_octet_string_worked = false; - if(m_print_context_specific) - { - try - { - if(possibly_a_general_name(bits.data(), bits.size())) - { - output << format(type_tag, class_tag, level, level, - std::string(cast_uint8_ptr_to_char(&bits[2]), bits.size() - 2)); - success_parsing_cs = true; - } - else if(recurse_deeper) - { - std::vector inner_bits; - data.decode(inner_bits, type_tag); + if (recurse_deeper) { + try { + BER_Decoder inner(decoded_bits); - BER_Decoder inner(inner_bits); - std::ostringstream inner_data; - decode(inner_data, inner, level + 1); // recurse - output << inner_data.str(); - success_parsing_cs = true; - } - } - catch(...) - { - } + std::ostringstream inner_data; + decode(inner_data, inner, level + 1); // recurse + + output << format(type_tag, class_tag, level, length, ""); + output << inner_data.str(); + printing_octet_string_worked = true; + } catch (...) { + } } - if(success_parsing_cs == false) - { - output << format(type_tag, class_tag, level, length, - format_bin(type_tag, class_tag, bits)); + if (!printing_octet_string_worked) { + output << format(type_tag, class_tag, level, length, + format_bin(type_tag, class_tag, decoded_bits)); } - } - else if(type_tag == OBJECT_ID) - { - OID oid; - data.decode(oid); + } else if (ASN1_String::is_string_type(type_tag)) { + ASN1_String str; + data.decode(str); + output << format(type_tag, class_tag, level, length, str.value()); + } else if (type_tag == UTC_TIME || type_tag == GENERALIZED_TIME) { + X509_Time time; + data.decode(time); + output << format(type_tag, class_tag, level, length, time.readable_string()); + } else { + output << "Unknown ASN.1 tag class=" << static_cast(class_tag) + << " type=" << static_cast(type_tag) << "\n"; + } - std::string out = OIDS::oid2str_or_empty(oid); - if(out.empty()) - { - out = oid.to_string(); - } - else - { - out += " [" + oid.to_string() + "]"; - } - - output << format(type_tag, class_tag, level, length, out); - } - else if(type_tag == INTEGER || type_tag == ENUMERATED) - { - BigInt number; - - if(type_tag == INTEGER) - { - data.decode(number); - } - else if(type_tag == ENUMERATED) - { - data.decode(number, ENUMERATED, class_tag); - } - - std::vector rep = BigInt::encode(number); - if(rep.empty()) // if zero - rep.resize(1); - - output << format(type_tag, class_tag, level, length, hex_encode(rep)); - } - else if(type_tag == BOOLEAN) - { - bool boolean; - data.decode(boolean); - output << format(type_tag, class_tag, level, length, (boolean ? "true" : "false")); - } - else if(type_tag == NULL_TAG) - { - output << format(type_tag, class_tag, level, length, ""); - } - else if(type_tag == OCTET_STRING || type_tag == BIT_STRING) - { - std::vector decoded_bits; - data.decode(decoded_bits, type_tag); - bool printing_octet_string_worked = false; - - if(recurse_deeper) - { - try - { - BER_Decoder inner(decoded_bits); - - std::ostringstream inner_data; - decode(inner_data, inner, level + 1); // recurse - - output << format(type_tag, class_tag, level, length, ""); - output << inner_data.str(); - printing_octet_string_worked = true; - } - catch(...) - { - } - } - - if(!printing_octet_string_worked) - { - output << format(type_tag, class_tag, level, length, - format_bin(type_tag, class_tag, decoded_bits)); - } - } - else if(ASN1_String::is_string_type(type_tag)) - { - ASN1_String str; - data.decode(str); - output << format(type_tag, class_tag, level, length, str.value()); - } - else if(type_tag == UTC_TIME || type_tag == GENERALIZED_TIME) - { - X509_Time time; - data.decode(time); - output << format(type_tag, class_tag, level, length, time.readable_string()); - } - else - { - output << "Unknown ASN.1 tag class=" << static_cast(class_tag) - << " type=" << static_cast(type_tag) << "\n"; - } - - obj = decoder.get_next_object(); - } - } + obj = decoder.get_next_object(); + } +} namespace { -std::string format_type(ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(class_tag == UNIVERSAL) - return asn1_tag_to_string(type_tag); +std::string format_type(ASN1_Tag type_tag, ASN1_Tag class_tag) { + if (class_tag == UNIVERSAL) return asn1_tag_to_string(type_tag); - if(class_tag == CONSTRUCTED && (type_tag == SEQUENCE || type_tag == SET)) - return asn1_tag_to_string(type_tag); + if (class_tag == CONSTRUCTED && (type_tag == SEQUENCE || type_tag == SET)) + return asn1_tag_to_string(type_tag); - std::string name; + std::string name; - if(class_tag & CONSTRUCTED) - name += "cons "; + if (class_tag & CONSTRUCTED) name += "cons "; - name += "[" + std::to_string(type_tag) + "]"; + name += "[" + std::to_string(type_tag) + "]"; - if(class_tag & APPLICATION) - { - name += " appl"; - } - if(class_tag & CONTEXT_SPECIFIC) - { - name += " context"; - } - - return name; - } + if (class_tag & APPLICATION) { + name += " appl"; + } + if (class_tag & CONTEXT_SPECIFIC) { + name += " context"; + } + return name; } -std::string ASN1_Pretty_Printer::format(ASN1_Tag type_tag, - ASN1_Tag class_tag, - size_t level, - size_t length, - const std::string& value) const - { - bool should_skip = false; +} // namespace - if(value.length() > m_print_limit) - { - should_skip = true; - } +std::string ASN1_Pretty_Printer::format(ASN1_Tag type_tag, ASN1_Tag class_tag, size_t level, + size_t length, const std::string& value) const { + bool should_skip = false; - if((type_tag == OCTET_STRING || type_tag == BIT_STRING) && - value.length() > m_print_binary_limit) - { - should_skip = true; - } + if (value.length() > m_print_limit) { + should_skip = true; + } - level += m_initial_level; + if ((type_tag == OCTET_STRING || type_tag == BIT_STRING) && + value.length() > m_print_binary_limit) { + should_skip = true; + } - std::ostringstream oss; + level += m_initial_level; - oss << " d=" << std::setw(2) << level - << ", l=" << std::setw(4) << length << ":" - << std::string(level + 1, ' ') << format_type(type_tag, class_tag); + std::ostringstream oss; - if(value != "" && !should_skip) - { - const size_t current_pos = static_cast(oss.tellp()); - const size_t spaces_to_align = - (current_pos >= m_value_column) ? 1 : (m_value_column - current_pos); + oss << " d=" << std::setw(2) << level << ", l=" << std::setw(4) << length << ":" + << std::string(level + 1, ' ') << format_type(type_tag, class_tag); - oss << std::string(spaces_to_align, ' ') << value; - } + if (value != "" && !should_skip) { + const size_t current_pos = static_cast(oss.tellp()); + const size_t spaces_to_align = + (current_pos >= m_value_column) ? 1 : (m_value_column - current_pos); - oss << "\n"; + oss << std::string(spaces_to_align, ' ') << value; + } - return oss.str(); - } - -std::string ASN1_Pretty_Printer::format_bin(ASN1_Tag /*type_tag*/, - ASN1_Tag /*class_tag*/, - const std::vector& vec) const - { - if(all_printable_chars(vec.data(), vec.size())) - { - return std::string(cast_uint8_ptr_to_char(vec.data()), vec.size()); - } - else - return hex_encode(vec); - } + oss << "\n"; + return oss.str(); } + +std::string ASN1_Pretty_Printer::format_bin(ASN1_Tag /*type_tag*/, ASN1_Tag /*class_tag*/, + const std::vector& vec) const { + if (all_printable_chars(vec.data(), vec.size())) { + return std::string(cast_uint8_ptr_to_char(vec.data()), vec.size()); + } else + return hex_encode(vec); +} + +} // namespace Botan /* -* Simple ASN.1 String Types -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Simple ASN.1 String Types + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { /* -* Choose an encoding for the string -*/ -ASN1_Tag choose_encoding(const std::string& str) - { - static const uint8_t IS_PRINTABLE[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - - for(size_t i = 0; i != str.size(); ++i) - { - if(!IS_PRINTABLE[static_cast(str[i])]) - { - return UTF8_STRING; - } - } - return PRINTABLE_STRING; - } - -void assert_is_string_type(ASN1_Tag tag) - { - if(!ASN1_String::is_string_type(tag)) - { - throw Invalid_Argument("ASN1_String: Unknown string type " + - std::to_string(tag)); - } - } + * Choose an encoding for the string + */ +ASN1_Tag choose_encoding(const std::string& str) { + static const uint8_t IS_PRINTABLE[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}; + for (size_t i = 0; i != str.size(); ++i) { + if (!IS_PRINTABLE[static_cast(str[i])]) { + return UTF8_STRING; + } + } + return PRINTABLE_STRING; } -//static -bool ASN1_String::is_string_type(ASN1_Tag tag) - { - return (tag == NUMERIC_STRING || - tag == PRINTABLE_STRING || - tag == VISIBLE_STRING || - tag == T61_STRING || - tag == IA5_STRING || - tag == UTF8_STRING || - tag == BMP_STRING || - tag == UNIVERSAL_STRING); - } - - -/* -* Create an ASN1_String -*/ -ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : m_utf8_str(str), m_tag(t) - { - if(m_tag == DIRECTORY_STRING) - { - m_tag = choose_encoding(m_utf8_str); - } - - assert_is_string_type(m_tag); - } - -/* -* Create an ASN1_String -*/ -ASN1_String::ASN1_String(const std::string& str) : - m_utf8_str(str), - m_tag(choose_encoding(m_utf8_str)) - {} - -/* -* Return this string in ISO 8859-1 encoding -*/ -std::string ASN1_String::iso_8859() const - { - return utf8_to_latin1(m_utf8_str); - } - -/* -* DER encode an ASN1_String -*/ -void ASN1_String::encode_into(DER_Encoder& encoder) const - { - if(m_data.empty()) - { - encoder.add_object(tagging(), UNIVERSAL, m_utf8_str); - } - else - { - // If this string was decoded, reserialize using original encoding - encoder.add_object(tagging(), UNIVERSAL, m_data.data(), m_data.size()); - } - } - -/* -* Decode a BER encoded ASN1_String -*/ -void ASN1_String::decode_from(BER_Decoder& source) - { - BER_Object obj = source.get_next_object(); - - assert_is_string_type(obj.type()); - - m_tag = obj.type(); - m_data.assign(obj.bits(), obj.bits() + obj.length()); - - if(m_tag == BMP_STRING) - { - m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size()); - } - else if(m_tag == UNIVERSAL_STRING) - { - m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size()); - } - else - { - // All other supported string types are UTF-8 or some subset thereof - m_utf8_str = ASN1::to_string(obj); - } - } - +void assert_is_string_type(ASN1_Tag tag) { + if (!ASN1_String::is_string_type(tag)) { + throw Invalid_Argument("ASN1_String: Unknown string type " + std::to_string(tag)); + } } -/* -* X.509 Time Types -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace + +// static +bool ASN1_String::is_string_type(ASN1_Tag tag) { + return (tag == NUMERIC_STRING || tag == PRINTABLE_STRING || tag == VISIBLE_STRING || + tag == T61_STRING || tag == IA5_STRING || tag == UTF8_STRING || tag == BMP_STRING || + tag == UNIVERSAL_STRING); +} + +/* + * Create an ASN1_String + */ +ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : m_utf8_str(str), m_tag(t) { + if (m_tag == DIRECTORY_STRING) { + m_tag = choose_encoding(m_utf8_str); + } + + assert_is_string_type(m_tag); +} + +/* + * Create an ASN1_String + */ +ASN1_String::ASN1_String(const std::string& str) + : m_utf8_str(str), m_tag(choose_encoding(m_utf8_str)) {} + +/* + * Return this string in ISO 8859-1 encoding + */ +std::string ASN1_String::iso_8859() const { return utf8_to_latin1(m_utf8_str); } + +/* + * DER encode an ASN1_String + */ +void ASN1_String::encode_into(DER_Encoder& encoder) const { + if (m_data.empty()) { + encoder.add_object(tagging(), UNIVERSAL, m_utf8_str); + } else { + // If this string was decoded, reserialize using original encoding + encoder.add_object(tagging(), UNIVERSAL, m_data.data(), m_data.size()); + } +} + +/* + * Decode a BER encoded ASN1_String + */ +void ASN1_String::decode_from(BER_Decoder& source) { + BER_Object obj = source.get_next_object(); + + assert_is_string_type(obj.type()); + + m_tag = obj.type(); + m_data.assign(obj.bits(), obj.bits() + obj.length()); + + if (m_tag == BMP_STRING) { + m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size()); + } else if (m_tag == UNIVERSAL_STRING) { + m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size()); + } else { + // All other supported string types are UTF-8 or some subset thereof + m_utf8_str = ASN1::to_string(obj); + } +} + +} // namespace Botan +/* + * X.509 Time Types + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -X509_Time::X509_Time(const std::chrono::system_clock::time_point& time) - { - calendar_point cal = calendar_value(time); +X509_Time::X509_Time(const std::chrono::system_clock::time_point& time) { + calendar_point cal = calendar_value(time); - m_year = cal.get_year(); - m_month = cal.get_month(); - m_day = cal.get_day(); - m_hour = cal.get_hour(); - m_minute = cal.get_minutes(); - m_second = cal.get_seconds(); - - m_tag = (m_year >= 2050) ? GENERALIZED_TIME : UTC_TIME; - } - -X509_Time::X509_Time(const std::string& t_spec, ASN1_Tag tag) - { - set_to(t_spec, tag); - } - -void X509_Time::encode_into(DER_Encoder& der) const - { - BOTAN_ARG_CHECK(m_tag == UTC_TIME || m_tag == GENERALIZED_TIME, - "X509_Time: Bad encoding tag"); - - der.add_object(m_tag, UNIVERSAL, to_string()); - } - -void X509_Time::decode_from(BER_Decoder& source) - { - BER_Object ber_time = source.get_next_object(); - - set_to(ASN1::to_string(ber_time), ber_time.type()); - } - -std::string X509_Time::to_string() const - { - if(time_is_set() == false) - throw Invalid_State("X509_Time::to_string: No time set"); - - uint32_t full_year = m_year; - - if(m_tag == UTC_TIME) - { - if(m_year < 1950 || m_year >= 2050) - throw Encoding_Error("X509_Time: The time " + readable_string() + - " cannot be encoded as a UTCTime"); - - full_year = (m_year >= 2000) ? (m_year - 2000) : (m_year - 1900); - } - - const uint64_t YEAR_FACTOR = 10000000000ULL; - const uint64_t MON_FACTOR = 100000000; - const uint64_t DAY_FACTOR = 1000000; - const uint64_t HOUR_FACTOR = 10000; - const uint64_t MIN_FACTOR = 100; - - const uint64_t int_repr = - YEAR_FACTOR * full_year + - MON_FACTOR * m_month + - DAY_FACTOR * m_day + - HOUR_FACTOR * m_hour + - MIN_FACTOR * m_minute + - m_second; - - std::string repr = std::to_string(int_repr) + "Z"; - - uint32_t desired_size = (m_tag == UTC_TIME) ? 13 : 15; - - while(repr.size() < desired_size) - repr = "0" + repr; - - return repr; - } - -std::string X509_Time::readable_string() const - { - if(time_is_set() == false) - throw Invalid_State("X509_Time::readable_string: No time set"); - - // desired format: "%04d/%02d/%02d %02d:%02d:%02d UTC" - std::stringstream output; - output << std::setfill('0') - << std::setw(4) << m_year << "/" - << std::setw(2) << m_month << "/" - << std::setw(2) << m_day - << " " - << std::setw(2) << m_hour << ":" - << std::setw(2) << m_minute << ":" - << std::setw(2) << m_second - << " UTC"; - - return output.str(); - } - -bool X509_Time::time_is_set() const - { - return (m_year != 0); - } - -int32_t X509_Time::cmp(const X509_Time& other) const - { - if(time_is_set() == false) - throw Invalid_State("X509_Time::cmp: No time set"); - - const int32_t EARLIER = -1, LATER = 1, SAME_TIME = 0; - - if(m_year < other.m_year) return EARLIER; - if(m_year > other.m_year) return LATER; - if(m_month < other.m_month) return EARLIER; - if(m_month > other.m_month) return LATER; - if(m_day < other.m_day) return EARLIER; - if(m_day > other.m_day) return LATER; - if(m_hour < other.m_hour) return EARLIER; - if(m_hour > other.m_hour) return LATER; - if(m_minute < other.m_minute) return EARLIER; - if(m_minute > other.m_minute) return LATER; - if(m_second < other.m_second) return EARLIER; - if(m_second > other.m_second) return LATER; - - return SAME_TIME; - } - -void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag) - { - if(spec_tag == UTC_OR_GENERALIZED_TIME) - { - try - { - set_to(t_spec, GENERALIZED_TIME); - return; - } - catch(Invalid_Argument&) {} // Not a generalized time. Continue - - try - { - set_to(t_spec, UTC_TIME); - return; - } - catch(Invalid_Argument&) {} // Not a UTC time. Continue - - throw Invalid_Argument("Time string could not be parsed as GeneralizedTime or UTCTime."); - } - - BOTAN_ASSERT(spec_tag == UTC_TIME || spec_tag == GENERALIZED_TIME, "Invalid tag."); - - BOTAN_ARG_CHECK(t_spec.size() > 0, "Time string must not be empty."); - - BOTAN_ARG_CHECK(t_spec.back() == 'Z', "Botan does not support times with timezones other than Z"); - - if(spec_tag == GENERALIZED_TIME) - { - BOTAN_ARG_CHECK(t_spec.size() == 15, "Invalid GeneralizedTime string"); - } - else if(spec_tag == UTC_TIME) - { - BOTAN_ARG_CHECK(t_spec.size() == 13, "Invalid UTCTime string"); - } - - const size_t YEAR_SIZE = (spec_tag == UTC_TIME) ? 2 : 4; - - std::vector params; - std::string current; - - for(size_t j = 0; j != YEAR_SIZE; ++j) - current += t_spec[j]; - params.push_back(current); - current.clear(); - - for(size_t j = YEAR_SIZE; j != t_spec.size() - 1; ++j) - { - current += t_spec[j]; - if(current.size() == 2) - { - params.push_back(current); - current.clear(); - } - } - - m_year = to_u32bit(params[0]); - m_month = to_u32bit(params[1]); - m_day = to_u32bit(params[2]); - m_hour = to_u32bit(params[3]); - m_minute = to_u32bit(params[4]); - m_second = (params.size() == 6) ? to_u32bit(params[5]) : 0; - m_tag = spec_tag; - - if(spec_tag == UTC_TIME) - { - if(m_year >= 50) m_year += 1900; - else m_year += 2000; - } - - if(!passes_sanity_check()) - throw Invalid_Argument("Time " + t_spec + " does not seem to be valid"); - } - -/* -* Do a general sanity check on the time -*/ -bool X509_Time::passes_sanity_check() const - { - // AppVeyor's trust store includes a cert with expiration date in 3016 ... - if(m_year < 1950 || m_year > 3100) - return false; - if(m_month == 0 || m_month > 12) - return false; - - const uint32_t days_in_month[12] = { 31, 28+1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - - if(m_day == 0 || m_day > days_in_month[m_month-1]) - return false; - - if(m_month == 2 && m_day == 29) - { - if(m_year % 4 != 0) - return false; // not a leap year - - if(m_year % 100 == 0 && m_year % 400 != 0) - return false; - } - - if(m_hour >= 24 || m_minute >= 60 || m_second > 60) - return false; - - if (m_tag == UTC_TIME) - { - /* - UTCTime limits the value of components such that leap seconds - are not covered. See "UNIVERSAL 23" in "Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation" - - http://www.itu.int/ITU-T/studygroups/com17/languages/ - */ - if(m_second > 59) - { - return false; - } - } - - return true; - } - -std::chrono::system_clock::time_point X509_Time::to_std_timepoint() const - { - return calendar_point(m_year, m_month, m_day, m_hour, m_minute, m_second).to_std_timepoint(); - } - -uint64_t X509_Time::time_since_epoch() const - { - auto tp = this->to_std_timepoint(); - return std::chrono::duration_cast(tp.time_since_epoch()).count(); - } - -/* -* Compare two X509_Times for in various ways -*/ -bool operator==(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) == 0); } -bool operator!=(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) != 0); } - -bool operator<=(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) <= 0); } -bool operator>=(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) >= 0); } - -bool operator<(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) < 0); } -bool operator>(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) > 0); } + m_year = cal.get_year(); + m_month = cal.get_month(); + m_day = cal.get_day(); + m_hour = cal.get_hour(); + m_minute = cal.get_minutes(); + m_second = cal.get_seconds(); + m_tag = (m_year >= 2050) ? GENERALIZED_TIME : UTC_TIME; } -/* -* BER Decoder -* (C) 1999-2008,2015,2017,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +X509_Time::X509_Time(const std::string& t_spec, ASN1_Tag tag) { set_to(t_spec, tag); } + +void X509_Time::encode_into(DER_Encoder& der) const { + BOTAN_ARG_CHECK(m_tag == UTC_TIME || m_tag == GENERALIZED_TIME, "X509_Time: Bad encoding tag"); + + der.add_object(m_tag, UNIVERSAL, to_string()); +} + +void X509_Time::decode_from(BER_Decoder& source) { + BER_Object ber_time = source.get_next_object(); + + set_to(ASN1::to_string(ber_time), ber_time.type()); +} + +std::string X509_Time::to_string() const { + if (time_is_set() == false) throw Invalid_State("X509_Time::to_string: No time set"); + + uint32_t full_year = m_year; + + if (m_tag == UTC_TIME) { + if (m_year < 1950 || m_year >= 2050) + throw Encoding_Error("X509_Time: The time " + readable_string() + + " cannot be encoded as a UTCTime"); + + full_year = (m_year >= 2000) ? (m_year - 2000) : (m_year - 1900); + } + + const uint64_t YEAR_FACTOR = 10000000000ULL; + const uint64_t MON_FACTOR = 100000000; + const uint64_t DAY_FACTOR = 1000000; + const uint64_t HOUR_FACTOR = 10000; + const uint64_t MIN_FACTOR = 100; + + const uint64_t int_repr = YEAR_FACTOR * full_year + MON_FACTOR * m_month + DAY_FACTOR * m_day + + HOUR_FACTOR * m_hour + MIN_FACTOR * m_minute + m_second; + + std::string repr = std::to_string(int_repr) + "Z"; + + uint32_t desired_size = (m_tag == UTC_TIME) ? 13 : 15; + + while (repr.size() < desired_size) repr = "0" + repr; + + return repr; +} + +std::string X509_Time::readable_string() const { + if (time_is_set() == false) throw Invalid_State("X509_Time::readable_string: No time set"); + + // desired format: "%04d/%02d/%02d %02d:%02d:%02d UTC" + std::stringstream output; + output << std::setfill('0') << std::setw(4) << m_year << "/" << std::setw(2) << m_month << "/" + << std::setw(2) << m_day << " " << std::setw(2) << m_hour << ":" << std::setw(2) + << m_minute << ":" << std::setw(2) << m_second << " UTC"; + + return output.str(); +} + +bool X509_Time::time_is_set() const { return (m_year != 0); } + +int32_t X509_Time::cmp(const X509_Time& other) const { + if (time_is_set() == false) throw Invalid_State("X509_Time::cmp: No time set"); + + const int32_t EARLIER = -1, LATER = 1, SAME_TIME = 0; + + if (m_year < other.m_year) return EARLIER; + if (m_year > other.m_year) return LATER; + if (m_month < other.m_month) return EARLIER; + if (m_month > other.m_month) return LATER; + if (m_day < other.m_day) return EARLIER; + if (m_day > other.m_day) return LATER; + if (m_hour < other.m_hour) return EARLIER; + if (m_hour > other.m_hour) return LATER; + if (m_minute < other.m_minute) return EARLIER; + if (m_minute > other.m_minute) return LATER; + if (m_second < other.m_second) return EARLIER; + if (m_second > other.m_second) return LATER; + + return SAME_TIME; +} + +void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag) { + if (spec_tag == UTC_OR_GENERALIZED_TIME) { + try { + set_to(t_spec, GENERALIZED_TIME); + return; + } catch (Invalid_Argument&) { + } // Not a generalized time. Continue + + try { + set_to(t_spec, UTC_TIME); + return; + } catch (Invalid_Argument&) { + } // Not a UTC time. Continue + + throw Invalid_Argument("Time string could not be parsed as GeneralizedTime or UTCTime."); + } + + BOTAN_ASSERT(spec_tag == UTC_TIME || spec_tag == GENERALIZED_TIME, "Invalid tag."); + + BOTAN_ARG_CHECK(t_spec.size() > 0, "Time string must not be empty."); + + BOTAN_ARG_CHECK(t_spec.back() == 'Z', + "Botan does not support times with timezones other than Z"); + + if (spec_tag == GENERALIZED_TIME) { + BOTAN_ARG_CHECK(t_spec.size() == 15, "Invalid GeneralizedTime string"); + } else if (spec_tag == UTC_TIME) { + BOTAN_ARG_CHECK(t_spec.size() == 13, "Invalid UTCTime string"); + } + + const size_t YEAR_SIZE = (spec_tag == UTC_TIME) ? 2 : 4; + + std::vector params; + std::string current; + + for (size_t j = 0; j != YEAR_SIZE; ++j) current += t_spec[j]; + params.push_back(current); + current.clear(); + + for (size_t j = YEAR_SIZE; j != t_spec.size() - 1; ++j) { + current += t_spec[j]; + if (current.size() == 2) { + params.push_back(current); + current.clear(); + } + } + + m_year = to_u32bit(params[0]); + m_month = to_u32bit(params[1]); + m_day = to_u32bit(params[2]); + m_hour = to_u32bit(params[3]); + m_minute = to_u32bit(params[4]); + m_second = (params.size() == 6) ? to_u32bit(params[5]) : 0; + m_tag = spec_tag; + + if (spec_tag == UTC_TIME) { + if (m_year >= 50) + m_year += 1900; + else + m_year += 2000; + } + + if (!passes_sanity_check()) + throw Invalid_Argument("Time " + t_spec + " does not seem to be valid"); +} + +/* + * Do a general sanity check on the time + */ +bool X509_Time::passes_sanity_check() const { + // AppVeyor's trust store includes a cert with expiration date in 3016 ... + if (m_year < 1950 || m_year > 3100) return false; + if (m_month == 0 || m_month > 12) return false; + + const uint32_t days_in_month[12] = {31, 28 + 1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + if (m_day == 0 || m_day > days_in_month[m_month - 1]) return false; + + if (m_month == 2 && m_day == 29) { + if (m_year % 4 != 0) return false; // not a leap year + + if (m_year % 100 == 0 && m_year % 400 != 0) return false; + } + + if (m_hour >= 24 || m_minute >= 60 || m_second > 60) return false; + + if (m_tag == UTC_TIME) { + /* + UTCTime limits the value of components such that leap seconds + are not covered. See "UNIVERSAL 23" in "Information technology + Abstract Syntax Notation One (ASN.1): Specification of basic notation" + + http://www.itu.int/ITU-T/studygroups/com17/languages/ + */ + if (m_second > 59) { + return false; + } + } + + return true; +} + +std::chrono::system_clock::time_point X509_Time::to_std_timepoint() const { + return calendar_point(m_year, m_month, m_day, m_hour, m_minute, m_second).to_std_timepoint(); +} + +uint64_t X509_Time::time_since_epoch() const { + auto tp = this->to_std_timepoint(); + return std::chrono::duration_cast(tp.time_since_epoch()).count(); +} + +/* + * Compare two X509_Times for in various ways + */ +bool operator==(const X509_Time& t1, const X509_Time& t2) { return (t1.cmp(t2) == 0); } +bool operator!=(const X509_Time& t1, const X509_Time& t2) { return (t1.cmp(t2) != 0); } + +bool operator<=(const X509_Time& t1, const X509_Time& t2) { return (t1.cmp(t2) <= 0); } +bool operator>=(const X509_Time& t1, const X509_Time& t2) { return (t1.cmp(t2) >= 0); } + +bool operator<(const X509_Time& t1, const X509_Time& t2) { return (t1.cmp(t2) < 0); } +bool operator>(const X509_Time& t1, const X509_Time& t2) { return (t1.cmp(t2) > 0); } + +} // namespace Botan +/* + * BER Decoder + * (C) 1999-2008,2015,2017,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { /* -* This value is somewhat arbitrary. OpenSSL allows up to 128 nested -* indefinite length sequences. If you increase this, also increase the -* limit in the test in test_asn1.cpp -*/ + * This value is somewhat arbitrary. OpenSSL allows up to 128 nested + * indefinite length sequences. If you increase this, also increase the + * limit in the test in test_asn1.cpp + */ const size_t ALLOWED_EOC_NESTINGS = 16; /* -* BER decode an ASN.1 type tag -*/ -size_t decode_tag(DataSource* ber, ASN1_Tag& type_tag, ASN1_Tag& class_tag) - { - uint8_t b; - if(!ber->read_byte(b)) - { - class_tag = type_tag = NO_OBJECT; - return 0; - } + * BER decode an ASN.1 type tag + */ +size_t decode_tag(DataSource* ber, ASN1_Tag& type_tag, ASN1_Tag& class_tag) { + uint8_t b; + if (!ber->read_byte(b)) { + class_tag = type_tag = NO_OBJECT; + return 0; + } - if((b & 0x1F) != 0x1F) - { - type_tag = ASN1_Tag(b & 0x1F); - class_tag = ASN1_Tag(b & 0xE0); - return 1; - } + if ((b & 0x1F) != 0x1F) { + type_tag = ASN1_Tag(b & 0x1F); + class_tag = ASN1_Tag(b & 0xE0); + return 1; + } - size_t tag_bytes = 1; - class_tag = ASN1_Tag(b & 0xE0); + size_t tag_bytes = 1; + class_tag = ASN1_Tag(b & 0xE0); - size_t tag_buf = 0; - while(true) - { - if(!ber->read_byte(b)) - throw BER_Decoding_Error("Long-form tag truncated"); - if(tag_buf & 0xFF000000) - throw BER_Decoding_Error("Long-form tag overflowed 32 bits"); - ++tag_bytes; - tag_buf = (tag_buf << 7) | (b & 0x7F); - if((b & 0x80) == 0) break; - } - type_tag = ASN1_Tag(tag_buf); - return tag_bytes; - } + size_t tag_buf = 0; + while (true) { + if (!ber->read_byte(b)) throw BER_Decoding_Error("Long-form tag truncated"); + if (tag_buf & 0xFF000000) throw BER_Decoding_Error("Long-form tag overflowed 32 bits"); + ++tag_bytes; + tag_buf = (tag_buf << 7) | (b & 0x7F); + if ((b & 0x80) == 0) break; + } + type_tag = ASN1_Tag(tag_buf); + return tag_bytes; +} /* -* Find the EOC marker -*/ + * Find the EOC marker + */ size_t find_eoc(DataSource* src, size_t allow_indef); /* -* BER decode an ASN.1 length field -*/ -size_t decode_length(DataSource* ber, size_t& field_size, size_t allow_indef) - { - uint8_t b; - if(!ber->read_byte(b)) - throw BER_Decoding_Error("Length field not found"); - field_size = 1; - if((b & 0x80) == 0) - return b; - - field_size += (b & 0x7F); - if(field_size > 5) - throw BER_Decoding_Error("Length field is too large"); - - if(field_size == 1) - { - if(allow_indef == 0) - { - throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion"); - } - else - { - return find_eoc(ber, allow_indef - 1); - } - } - - size_t length = 0; - - for(size_t i = 0; i != field_size - 1; ++i) - { - if(get_byte(0, length) != 0) - throw BER_Decoding_Error("Field length overflow"); - if(!ber->read_byte(b)) - throw BER_Decoding_Error("Corrupted length field"); - length = (length << 8) | b; - } - return length; - } - -/* -* Find the EOC marker -*/ -size_t find_eoc(DataSource* ber, size_t allow_indef) - { - secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE), data; - - while(true) - { - const size_t got = ber->peek(buffer.data(), buffer.size(), data.size()); - if(got == 0) - break; - - data += std::make_pair(buffer.data(), got); - } - - DataSource_Memory source(data); - data.clear(); - - size_t length = 0; - while(true) - { - ASN1_Tag type_tag, class_tag; - size_t tag_size = decode_tag(&source, type_tag, class_tag); - if(type_tag == NO_OBJECT) - break; - - size_t length_size = 0; - size_t item_size = decode_length(&source, length_size, allow_indef); - source.discard_next(item_size); - - length = BOTAN_CHECKED_ADD(length, item_size); - length = BOTAN_CHECKED_ADD(length, tag_size); - length = BOTAN_CHECKED_ADD(length, length_size); - - if(type_tag == EOC && class_tag == UNIVERSAL) - break; - } - return length; - } - -class DataSource_BERObject final : public DataSource - { - public: - size_t read(uint8_t out[], size_t length) override - { - BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); - const size_t got = std::min(m_obj.length() - m_offset, length); - copy_mem(out, m_obj.bits() + m_offset, got); - m_offset += got; - return got; - } - - size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override - { - BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); - const size_t bytes_left = m_obj.length() - m_offset; - - if(peek_offset >= bytes_left) - return 0; - - const size_t got = std::min(bytes_left - peek_offset, length); - copy_mem(out, m_obj.bits() + peek_offset, got); - return got; - } - - bool check_available(size_t n) override - { - BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); - return (n <= (m_obj.length() - m_offset)); - } - - bool end_of_data() const override - { - return get_bytes_read() == m_obj.length(); - } - - size_t get_bytes_read() const override { return m_offset; } - - explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)), m_offset(0) {} - - private: - BER_Object m_obj; - size_t m_offset; - }; - -} - -/* -* Check if more objects are there -*/ -bool BER_Decoder::more_items() const - { - if(m_source->end_of_data() && !m_pushed.is_set()) - return false; - return true; - } - -/* -* Verify that no bytes remain in the source -*/ -BER_Decoder& BER_Decoder::verify_end() - { - return verify_end("BER_Decoder::verify_end called, but data remains"); - } - -/* -* Verify that no bytes remain in the source -*/ -BER_Decoder& BER_Decoder::verify_end(const std::string& err) - { - if(!m_source->end_of_data() || m_pushed.is_set()) - throw Decoding_Error(err); - return (*this); - } - -/* -* Discard all the bytes remaining in the source -*/ -BER_Decoder& BER_Decoder::discard_remaining() - { - uint8_t buf; - while(m_source->read_byte(buf)) - {} - return (*this); - } - -/* -* Return the BER encoding of the next object -*/ -BER_Object BER_Decoder::get_next_object() - { - BER_Object next; - - if(m_pushed.is_set()) - { - std::swap(next, m_pushed); - return next; - } - - for(;;) - { - ASN1_Tag type_tag, class_tag; - decode_tag(m_source, type_tag, class_tag); - next.set_tagging(type_tag, class_tag); - if(next.is_set() == false) // no more objects - return next; - - size_t field_size; - const size_t length = decode_length(m_source, field_size, ALLOWED_EOC_NESTINGS); - if(!m_source->check_available(length)) - throw BER_Decoding_Error("Value truncated"); - - uint8_t* out = next.mutable_bits(length); - if(m_source->read(out, length) != length) - throw BER_Decoding_Error("Value truncated"); - - if(next.tagging() == EOC) - continue; - else - break; - } - - return next; - } - -/* -* Push a object back into the stream -*/ -void BER_Decoder::push_back(const BER_Object& obj) - { - if(m_pushed.is_set()) - throw Invalid_State("BER_Decoder: Only one push back is allowed"); - m_pushed = obj; - } - -void BER_Decoder::push_back(BER_Object&& obj) - { - if(m_pushed.is_set()) - throw Invalid_State("BER_Decoder: Only one push back is allowed"); - m_pushed = std::move(obj); - } - -BER_Decoder BER_Decoder::start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag) - { - BER_Object obj = get_next_object(); - obj.assert_is_a(type_tag, ASN1_Tag(class_tag | CONSTRUCTED)); - return BER_Decoder(std::move(obj), this); - } - -/* -* Finish decoding a CONSTRUCTED type -*/ -BER_Decoder& BER_Decoder::end_cons() - { - if(!m_parent) - throw Invalid_State("BER_Decoder::end_cons called with null parent"); - if(!m_source->end_of_data()) - throw Decoding_Error("BER_Decoder::end_cons called with data left"); - return (*m_parent); - } - -BER_Decoder::BER_Decoder(BER_Object&& obj, BER_Decoder* parent) - { - m_data_src.reset(new DataSource_BERObject(std::move(obj))); - m_source = m_data_src.get(); - m_parent = parent; - } - -/* -* BER_Decoder Constructor -*/ -BER_Decoder::BER_Decoder(DataSource& src) - { - m_source = &src; - } - -/* -* BER_Decoder Constructor + * BER decode an ASN.1 length field */ -BER_Decoder::BER_Decoder(const uint8_t data[], size_t length) - { - m_data_src.reset(new DataSource_Memory(data, length)); - m_source = m_data_src.get(); - } +size_t decode_length(DataSource* ber, size_t& field_size, size_t allow_indef) { + uint8_t b; + if (!ber->read_byte(b)) throw BER_Decoding_Error("Length field not found"); + field_size = 1; + if ((b & 0x80) == 0) return b; -/* -* BER_Decoder Constructor -*/ -BER_Decoder::BER_Decoder(const secure_vector& data) - { - m_data_src.reset(new DataSource_Memory(data)); - m_source = m_data_src.get(); - } + field_size += (b & 0x7F); + if (field_size > 5) throw BER_Decoding_Error("Length field is too large"); -/* -* BER_Decoder Constructor -*/ -BER_Decoder::BER_Decoder(const std::vector& data) - { - m_data_src.reset(new DataSource_Memory(data.data(), data.size())); - m_source = m_data_src.get(); - } + if (field_size == 1) { + if (allow_indef == 0) { + throw BER_Decoding_Error( + "Nested EOC markers too deep, rejecting to avoid stack exhaustion"); + } else { + return find_eoc(ber, allow_indef - 1); + } + } -/* -* BER_Decoder Copy Constructor -*/ -BER_Decoder::BER_Decoder(const BER_Decoder& other) - { - m_source = other.m_source; - - // take ownership - std::swap(m_data_src, other.m_data_src); - m_parent = other.m_parent; - } - -/* -* Request for an object to decode itself -*/ -BER_Decoder& BER_Decoder::decode(ASN1_Object& obj, - ASN1_Tag, ASN1_Tag) - { - obj.decode_from(*this); - return (*this); - } - -/* -* Decode a BER encoded NULL -*/ -BER_Decoder& BER_Decoder::decode_null() - { - BER_Object obj = get_next_object(); - obj.assert_is_a(NULL_TAG, UNIVERSAL); - if(obj.length() > 0) - throw BER_Decoding_Error("NULL object had nonzero size"); - return (*this); - } - -BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) - { - secure_vector out_vec; - decode(out_vec, OCTET_STRING); - out = BigInt::decode(out_vec.data(), out_vec.size()); - return (*this); - } - -/* -* Decode a BER encoded BOOLEAN -*/ -BER_Decoder& BER_Decoder::decode(bool& out, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - BER_Object obj = get_next_object(); - obj.assert_is_a(type_tag, class_tag); - - if(obj.length() != 1) - throw BER_Decoding_Error("BER boolean value had invalid size"); - - out = (obj.bits()[0]) ? true : false; - return (*this); - } - -/* -* Decode a small BER encoded INTEGER -*/ -BER_Decoder& BER_Decoder::decode(size_t& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag) - { - BigInt integer; - decode(integer, type_tag, class_tag); - - if(integer.is_negative()) - throw BER_Decoding_Error("Decoded small integer value was negative"); - - if(integer.bits() > 32) - throw BER_Decoding_Error("Decoded integer value larger than expected"); - - out = 0; - for(size_t i = 0; i != 4; ++i) - out = (out << 8) | integer.byte_at(3-i); - - return (*this); - } - -/* -* Decode a small BER encoded INTEGER -*/ -uint64_t BER_Decoder::decode_constrained_integer(ASN1_Tag type_tag, - ASN1_Tag class_tag, - size_t T_bytes) - { - if(T_bytes > 8) - throw BER_Decoding_Error("Can't decode small integer over 8 bytes"); - - BigInt integer; - decode(integer, type_tag, class_tag); - - if(integer.bits() > 8*T_bytes) - throw BER_Decoding_Error("Decoded integer value larger than expected"); - - uint64_t out = 0; - for(size_t i = 0; i != 8; ++i) - out = (out << 8) | integer.byte_at(7-i); - - return out; - } - -/* -* Decode a BER encoded INTEGER -*/ -BER_Decoder& BER_Decoder::decode(BigInt& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag) - { - BER_Object obj = get_next_object(); - obj.assert_is_a(type_tag, class_tag); - - if(obj.length() == 0) - { - out = 0; - } - else - { - const bool negative = (obj.bits()[0] & 0x80) ? true : false; - - if(negative) - { - secure_vector vec(obj.bits(), obj.bits() + obj.length()); - for(size_t i = obj.length(); i > 0; --i) - if(vec[i-1]--) - break; - for(size_t i = 0; i != obj.length(); ++i) - vec[i] = ~vec[i]; - out = BigInt(vec.data(), vec.size()); - out.flip_sign(); - } - else - { - out = BigInt(obj.bits(), obj.length()); - } - } - - return (*this); - } - -namespace { - -template -void asn1_decode_binary_string(std::vector& buffer, - const BER_Object& obj, - ASN1_Tag real_type, - ASN1_Tag type_tag, - ASN1_Tag class_tag) - { - obj.assert_is_a(type_tag, class_tag); - - if(real_type == OCTET_STRING) - { - buffer.assign(obj.bits(), obj.bits() + obj.length()); - } - else - { - if(obj.length() == 0) - throw BER_Decoding_Error("Invalid BIT STRING"); - if(obj.bits()[0] >= 8) - throw BER_Decoding_Error("Bad number of unused bits in BIT STRING"); - - buffer.resize(obj.length() - 1); - - if(obj.length() > 1) - copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1); - } - } + size_t length = 0; + for (size_t i = 0; i != field_size - 1; ++i) { + if (get_byte(0, length) != 0) throw BER_Decoding_Error("Field length overflow"); + if (!ber->read_byte(b)) throw BER_Decoding_Error("Corrupted length field"); + length = (length << 8) | b; + } + return length; } /* -* BER decode a BIT STRING or OCTET STRING -*/ -BER_Decoder& BER_Decoder::decode(secure_vector& buffer, - ASN1_Tag real_type, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(real_type != OCTET_STRING && real_type != BIT_STRING) - throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type); + * Find the EOC marker + */ +size_t find_eoc(DataSource* ber, size_t allow_indef) { + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE), data; - asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag); - return (*this); - } + while (true) { + const size_t got = ber->peek(buffer.data(), buffer.size(), data.size()); + if (got == 0) break; -BER_Decoder& BER_Decoder::decode(std::vector& buffer, - ASN1_Tag real_type, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(real_type != OCTET_STRING && real_type != BIT_STRING) - throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type); + data += std::make_pair(buffer.data(), got); + } - asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag); - return (*this); - } + DataSource_Memory source(data); + data.clear(); -} -/* -* DER Encoder -* (C) 1999-2007,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + size_t length = 0; + while (true) { + ASN1_Tag type_tag, class_tag; + size_t tag_size = decode_tag(&source, type_tag, class_tag); + if (type_tag == NO_OBJECT) break; + size_t length_size = 0; + size_t item_size = decode_length(&source, length_size, allow_indef); + source.discard_next(item_size); -namespace Botan { - -namespace { - -/* -* DER encode an ASN.1 type tag -*/ -void encode_tag(std::vector& encoded_tag, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if((class_tag | 0xE0) != 0xE0) - throw Encoding_Error("DER_Encoder: Invalid class tag " + - std::to_string(class_tag)); - - if(type_tag <= 30) - { - encoded_tag.push_back(static_cast(type_tag | class_tag)); - } - else - { - size_t blocks = high_bit(static_cast(type_tag)) + 6; - blocks = (blocks - (blocks % 7)) / 7; - - BOTAN_ASSERT_NOMSG(blocks > 0); - - encoded_tag.push_back(static_cast(class_tag | 0x1F)); - for(size_t i = 0; i != blocks - 1; ++i) - encoded_tag.push_back(0x80 | ((type_tag >> 7*(blocks-i-1)) & 0x7F)); - encoded_tag.push_back(type_tag & 0x7F); - } - } - -/* -* DER encode an ASN.1 length field -*/ -void encode_length(std::vector& encoded_length, size_t length) - { - if(length <= 127) - { - encoded_length.push_back(static_cast(length)); - } - else - { - const size_t bytes_needed = significant_bytes(length); - - encoded_length.push_back(static_cast(0x80 | bytes_needed)); - - for(size_t i = sizeof(length) - bytes_needed; i < sizeof(length); ++i) - encoded_length.push_back(get_byte(i, length)); - } - } + length = BOTAN_CHECKED_ADD(length, item_size); + length = BOTAN_CHECKED_ADD(length, tag_size); + length = BOTAN_CHECKED_ADD(length, length_size); + if (type_tag == EOC && class_tag == UNIVERSAL) break; + } + return length; } -DER_Encoder::DER_Encoder(secure_vector& vec) - { - m_append_output = [&vec](const uint8_t b[], size_t l) - { - vec.insert(vec.end(), b, b + l); - }; - } - -DER_Encoder::DER_Encoder(std::vector& vec) - { - m_append_output = [&vec](const uint8_t b[], size_t l) - { - vec.insert(vec.end(), b, b + l); - }; - } - -/* -* Push the encoded SEQUENCE/SET to the encoder stream -*/ -void DER_Encoder::DER_Sequence::push_contents(DER_Encoder& der) - { - const ASN1_Tag real_class_tag = ASN1_Tag(m_class_tag | CONSTRUCTED); - - if(m_type_tag == SET) - { - std::sort(m_set_contents.begin(), m_set_contents.end()); - for(size_t i = 0; i != m_set_contents.size(); ++i) - m_contents += m_set_contents[i]; - m_set_contents.clear(); - } - - der.add_object(m_type_tag, real_class_tag, m_contents.data(), m_contents.size()); - m_contents.clear(); - } - -/* -* Add an encoded value to the SEQUENCE/SET -*/ -void DER_Encoder::DER_Sequence::add_bytes(const uint8_t data[], size_t length) - { - if(m_type_tag == SET) - m_set_contents.push_back(secure_vector(data, data + length)); - else - m_contents += std::make_pair(data, length); - } - -void DER_Encoder::DER_Sequence::add_bytes(const uint8_t hdr[], size_t hdr_len, - const uint8_t val[], size_t val_len) - { - if(m_type_tag == SET) - { - secure_vector m; - m.reserve(hdr_len + val_len); - m += std::make_pair(hdr, hdr_len); - m += std::make_pair(val, val_len); - m_set_contents.push_back(std::move(m)); - } - else - { - m_contents += std::make_pair(hdr, hdr_len); - m_contents += std::make_pair(val, val_len); - } - } - -/* -* Return the type and class taggings -*/ -ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const - { - return ASN1_Tag(m_type_tag | m_class_tag); - } - -/* -* DER_Sequence Constructor -*/ -DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) : - m_type_tag(t1), m_class_tag(t2) - { - } - -/* -* Return the encoded contents -*/ -secure_vector DER_Encoder::get_contents() - { - if(m_subsequences.size() != 0) - throw Invalid_State("DER_Encoder: Sequence hasn't been marked done"); - - if(m_append_output) - throw Invalid_State("DER_Encoder Cannot get contents when using output vector"); - - secure_vector output; - std::swap(output, m_default_outbuf); - return output; - } - -std::vector DER_Encoder::get_contents_unlocked() - { - if(m_subsequences.size() != 0) - throw Invalid_State("DER_Encoder: Sequence hasn't been marked done"); - - if(m_append_output) - throw Invalid_State("DER_Encoder Cannot get contents when using output vector"); - - std::vector output(m_default_outbuf.begin(), m_default_outbuf.end()); - m_default_outbuf.clear(); - return output; - } - -/* -* Start a new ASN.1 SEQUENCE/SET/EXPLICIT -*/ -DER_Encoder& DER_Encoder::start_cons(ASN1_Tag type_tag, - ASN1_Tag class_tag) - { - m_subsequences.push_back(DER_Sequence(type_tag, class_tag)); - return (*this); - } - -/* -* Finish the current ASN.1 SEQUENCE/SET/EXPLICIT -*/ -DER_Encoder& DER_Encoder::end_cons() - { - if(m_subsequences.empty()) - throw Invalid_State("DER_Encoder::end_cons: No such sequence"); - - DER_Sequence last_seq = std::move(m_subsequences[m_subsequences.size()-1]); - m_subsequences.pop_back(); - last_seq.push_contents(*this); - - return (*this); - } - -/* -* Start a new ASN.1 EXPLICIT encoding -*/ -DER_Encoder& DER_Encoder::start_explicit(uint16_t type_no) - { - ASN1_Tag type_tag = static_cast(type_no); - - // This would confuse DER_Sequence - if(type_tag == SET) - throw Internal_Error("DER_Encoder.start_explicit(SET) not supported"); - - return start_cons(type_tag, CONTEXT_SPECIFIC); - } - -/* -* Finish the current ASN.1 EXPLICIT encoding -*/ -DER_Encoder& DER_Encoder::end_explicit() - { - return end_cons(); - } - -/* -* Write raw bytes into the stream -*/ -DER_Encoder& DER_Encoder::raw_bytes(const uint8_t bytes[], size_t length) - { - if(m_subsequences.size()) - { - m_subsequences[m_subsequences.size()-1].add_bytes(bytes, length); - } - else if(m_append_output) - { - m_append_output(bytes, length); - } - else - { - m_default_outbuf += std::make_pair(bytes, length); - } - - return (*this); - } - -/* -* Write the encoding of the byte(s) -*/ -DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const uint8_t rep[], size_t length) - { - std::vector hdr; - encode_tag(hdr, type_tag, class_tag); - encode_length(hdr, length); - - if(m_subsequences.size()) - { - m_subsequences[m_subsequences.size()-1].add_bytes(hdr.data(), hdr.size(), rep, length); - } - else if(m_append_output) - { - m_append_output(hdr.data(), hdr.size()); - m_append_output(rep, length); - } - else - { - m_default_outbuf += hdr; - m_default_outbuf += std::make_pair(rep, length); - } - - return (*this); - } - -/* -* Encode a NULL object -*/ -DER_Encoder& DER_Encoder::encode_null() - { - return add_object(NULL_TAG, UNIVERSAL, nullptr, 0); - } - -/* -* DER encode a BOOLEAN -*/ -DER_Encoder& DER_Encoder::encode(bool is_true) - { - return encode(is_true, BOOLEAN, UNIVERSAL); - } - -/* -* DER encode a small INTEGER -*/ -DER_Encoder& DER_Encoder::encode(size_t n) - { - return encode(BigInt(n), INTEGER, UNIVERSAL); - } - -/* -* DER encode a small INTEGER -*/ -DER_Encoder& DER_Encoder::encode(const BigInt& n) - { - return encode(n, INTEGER, UNIVERSAL); - } - -/* -* Encode this object -*/ -DER_Encoder& DER_Encoder::encode(const uint8_t bytes[], size_t length, - ASN1_Tag real_type) - { - return encode(bytes, length, real_type, real_type, UNIVERSAL); - } - -/* -* DER encode a BOOLEAN -*/ -DER_Encoder& DER_Encoder::encode(bool is_true, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - uint8_t val = is_true ? 0xFF : 0x00; - return add_object(type_tag, class_tag, &val, 1); - } - -/* -* DER encode a small INTEGER -*/ -DER_Encoder& DER_Encoder::encode(size_t n, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - return encode(BigInt(n), type_tag, class_tag); - } - -/* -* DER encode an INTEGER -*/ -DER_Encoder& DER_Encoder::encode(const BigInt& n, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(n == 0) - return add_object(type_tag, class_tag, 0); - - const size_t extra_zero = (n.bits() % 8 == 0) ? 1 : 0; - secure_vector contents(extra_zero + n.bytes()); - n.binary_encode(&contents[extra_zero]); - if(n < 0) - { - for(size_t i = 0; i != contents.size(); ++i) - contents[i] = ~contents[i]; - for(size_t i = contents.size(); i > 0; --i) - if(++contents[i-1]) - break; - } - - return add_object(type_tag, class_tag, contents); - } - -/* -* DER encode an OCTET STRING or BIT STRING -*/ -DER_Encoder& DER_Encoder::encode(const uint8_t bytes[], size_t length, - ASN1_Tag real_type, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(real_type != OCTET_STRING && real_type != BIT_STRING) - throw Invalid_Argument("DER_Encoder: Invalid tag for byte/bit string"); - - if(real_type == BIT_STRING) - { - secure_vector encoded; - encoded.push_back(0); - encoded += std::make_pair(bytes, length); - return add_object(type_tag, class_tag, encoded); - } - else - return add_object(type_tag, class_tag, bytes, length); - } - -DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj) - { - obj.encode_into(*this); - return (*this); - } - -/* -* Write the encoding of the byte(s) -*/ -DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const std::string& rep_str) - { - const uint8_t* rep = cast_char_ptr_to_uint8(rep_str.data()); - const size_t rep_len = rep_str.size(); - return add_object(type_tag, class_tag, rep, rep_len); - } - -/* -* Write the encoding of the byte -*/ -DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, - ASN1_Tag class_tag, uint8_t rep) - { - return add_object(type_tag, class_tag, &rep, 1); - } - -} -/* -* OID maps -* -* This file was automatically generated by ./src/scripts/oids.py on 2019-08-03 -* -* All manual edits to this file will be lost. Edit the script -* then regenerate this source file. -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - -namespace Botan { - -std::unordered_map OIDS::load_oid2str_map() - { - return std::unordered_map{ - { "0.3.4401.5.3.1.9.26", "Camellia-192/GCM" }, - { "0.3.4401.5.3.1.9.46", "Camellia-256/GCM" }, - { "0.3.4401.5.3.1.9.6", "Camellia-128/GCM" }, - { "1.0.14888.3.0.5", "ECKCDSA" }, - { "1.2.156.10197.1.104.100", "SM4/OCB" }, - { "1.2.156.10197.1.104.2", "SM4/CBC" }, - { "1.2.156.10197.1.104.8", "SM4/GCM" }, - { "1.2.156.10197.1.301", "sm2p256v1" }, - { "1.2.156.10197.1.301.1", "SM2" }, - { "1.2.156.10197.1.301.2", "SM2_Kex" }, - { "1.2.156.10197.1.301.3", "SM2_Enc" }, - { "1.2.156.10197.1.401", "SM3" }, - { "1.2.156.10197.1.501", "SM2_Sig/SM3" }, - { "1.2.156.10197.1.504", "RSA/EMSA3(SM3)" }, - { "1.2.250.1.223.101.256.1", "frp256v1" }, - { "1.2.392.200011.61.1.1.1.2", "Camellia-128/CBC" }, - { "1.2.392.200011.61.1.1.1.3", "Camellia-192/CBC" }, - { "1.2.392.200011.61.1.1.1.4", "Camellia-256/CBC" }, - { "1.2.410.200004.1.100.4.3", "ECKCDSA/EMSA1(SHA-1)" }, - { "1.2.410.200004.1.100.4.4", "ECKCDSA/EMSA1(SHA-224)" }, - { "1.2.410.200004.1.100.4.5", "ECKCDSA/EMSA1(SHA-256)" }, - { "1.2.410.200004.1.4", "SEED/CBC" }, - { "1.2.643.100.1", "GOST.OGRN" }, - { "1.2.643.100.111", "GOST.SubjectSigningTool" }, - { "1.2.643.100.112", "GOST.IssuerSigningTool" }, - { "1.2.643.2.2.19", "GOST-34.10" }, - { "1.2.643.2.2.3", "GOST-34.10/EMSA1(GOST-R-34.11-94)" }, - { "1.2.643.2.2.35.1", "gost_256A" }, - { "1.2.643.2.2.36.0", "gost_256A" }, - { "1.2.643.3.131.1.1", "GOST.INN" }, - { "1.2.643.7.1.1.1.1", "GOST-34.10-2012-256" }, - { "1.2.643.7.1.1.1.2", "GOST-34.10-2012-512" }, - { "1.2.643.7.1.1.2.2", "Streebog-256" }, - { "1.2.643.7.1.1.2.3", "Streebog-512" }, - { "1.2.643.7.1.1.3.2", "GOST-34.10-2012-256/EMSA1(Streebog-256)" }, - { "1.2.643.7.1.1.3.3", "GOST-34.10-2012-512/EMSA1(Streebog-512)" }, - { "1.2.643.7.1.2.1.1.1", "gost_256A" }, - { "1.2.643.7.1.2.1.1.2", "gost_256B" }, - { "1.2.643.7.1.2.1.2.1", "gost_512A" }, - { "1.2.643.7.1.2.1.2.2", "gost_512B" }, - { "1.2.840.10040.4.1", "DSA" }, - { "1.2.840.10040.4.3", "DSA/EMSA1(SHA-160)" }, - { "1.2.840.10045.2.1", "ECDSA" }, - { "1.2.840.10045.3.1.1", "secp192r1" }, - { "1.2.840.10045.3.1.2", "x962_p192v2" }, - { "1.2.840.10045.3.1.3", "x962_p192v3" }, - { "1.2.840.10045.3.1.4", "x962_p239v1" }, - { "1.2.840.10045.3.1.5", "x962_p239v2" }, - { "1.2.840.10045.3.1.6", "x962_p239v3" }, - { "1.2.840.10045.3.1.7", "secp256r1" }, - { "1.2.840.10045.4.1", "ECDSA/EMSA1(SHA-160)" }, - { "1.2.840.10045.4.3.1", "ECDSA/EMSA1(SHA-224)" }, - { "1.2.840.10045.4.3.2", "ECDSA/EMSA1(SHA-256)" }, - { "1.2.840.10045.4.3.3", "ECDSA/EMSA1(SHA-384)" }, - { "1.2.840.10045.4.3.4", "ECDSA/EMSA1(SHA-512)" }, - { "1.2.840.10046.2.1", "DH" }, - { "1.2.840.113533.7.66.10", "CAST-128/CBC" }, - { "1.2.840.113533.7.66.15", "KeyWrap.CAST-128" }, - { "1.2.840.113549.1.1.1", "RSA" }, - { "1.2.840.113549.1.1.10", "RSA/EMSA4" }, - { "1.2.840.113549.1.1.11", "RSA/EMSA3(SHA-256)" }, - { "1.2.840.113549.1.1.12", "RSA/EMSA3(SHA-384)" }, - { "1.2.840.113549.1.1.13", "RSA/EMSA3(SHA-512)" }, - { "1.2.840.113549.1.1.14", "RSA/EMSA3(SHA-224)" }, - { "1.2.840.113549.1.1.16", "RSA/EMSA3(SHA-512-256)" }, - { "1.2.840.113549.1.1.4", "RSA/EMSA3(MD5)" }, - { "1.2.840.113549.1.1.5", "RSA/EMSA3(SHA-160)" }, - { "1.2.840.113549.1.1.7", "RSA/OAEP" }, - { "1.2.840.113549.1.1.8", "MGF1" }, - { "1.2.840.113549.1.5.12", "PKCS5.PBKDF2" }, - { "1.2.840.113549.1.5.13", "PBE-PKCS5v20" }, - { "1.2.840.113549.1.9.1", "PKCS9.EmailAddress" }, - { "1.2.840.113549.1.9.14", "PKCS9.ExtensionRequest" }, - { "1.2.840.113549.1.9.16.3.18", "ChaCha20Poly1305" }, - { "1.2.840.113549.1.9.16.3.6", "KeyWrap.TripleDES" }, - { "1.2.840.113549.1.9.16.3.8", "Compression.Zlib" }, - { "1.2.840.113549.1.9.2", "PKCS9.UnstructuredName" }, - { "1.2.840.113549.1.9.3", "PKCS9.ContentType" }, - { "1.2.840.113549.1.9.4", "PKCS9.MessageDigest" }, - { "1.2.840.113549.1.9.7", "PKCS9.ChallengePassword" }, - { "1.2.840.113549.2.10", "HMAC(SHA-384)" }, - { "1.2.840.113549.2.11", "HMAC(SHA-512)" }, - { "1.2.840.113549.2.13", "HMAC(SHA-512-256)" }, - { "1.2.840.113549.2.5", "MD5" }, - { "1.2.840.113549.2.7", "HMAC(SHA-160)" }, - { "1.2.840.113549.2.8", "HMAC(SHA-224)" }, - { "1.2.840.113549.2.9", "HMAC(SHA-256)" }, - { "1.2.840.113549.3.7", "TripleDES/CBC" }, - { "1.3.101.110", "Curve25519" }, - { "1.3.101.112", "Ed25519" }, - { "1.3.132.0.10", "secp256k1" }, - { "1.3.132.0.30", "secp160r2" }, - { "1.3.132.0.31", "secp192k1" }, - { "1.3.132.0.32", "secp224k1" }, - { "1.3.132.0.33", "secp224r1" }, - { "1.3.132.0.34", "secp384r1" }, - { "1.3.132.0.35", "secp521r1" }, - { "1.3.132.0.8", "secp160r1" }, - { "1.3.132.0.9", "secp160k1" }, - { "1.3.132.1.12", "ECDH" }, - { "1.3.14.3.2.26", "SHA-160" }, - { "1.3.14.3.2.7", "DES/CBC" }, - { "1.3.36.3.2.1", "RIPEMD-160" }, - { "1.3.36.3.3.1.2", "RSA/EMSA3(RIPEMD-160)" }, - { "1.3.36.3.3.2.5.2.1", "ECGDSA" }, - { "1.3.36.3.3.2.5.4.1", "ECGDSA/EMSA1(RIPEMD-160)" }, - { "1.3.36.3.3.2.5.4.2", "ECGDSA/EMSA1(SHA-160)" }, - { "1.3.36.3.3.2.5.4.3", "ECGDSA/EMSA1(SHA-224)" }, - { "1.3.36.3.3.2.5.4.4", "ECGDSA/EMSA1(SHA-256)" }, - { "1.3.36.3.3.2.5.4.5", "ECGDSA/EMSA1(SHA-384)" }, - { "1.3.36.3.3.2.5.4.6", "ECGDSA/EMSA1(SHA-512)" }, - { "1.3.36.3.3.2.8.1.1.1", "brainpool160r1" }, - { "1.3.36.3.3.2.8.1.1.11", "brainpool384r1" }, - { "1.3.36.3.3.2.8.1.1.13", "brainpool512r1" }, - { "1.3.36.3.3.2.8.1.1.3", "brainpool192r1" }, - { "1.3.36.3.3.2.8.1.1.5", "brainpool224r1" }, - { "1.3.36.3.3.2.8.1.1.7", "brainpool256r1" }, - { "1.3.36.3.3.2.8.1.1.9", "brainpool320r1" }, - { "1.3.6.1.4.1.11591.12.2", "Tiger(24,3)" }, - { "1.3.6.1.4.1.11591.15.1", "OpenPGP.Ed25519" }, - { "1.3.6.1.4.1.11591.4.11", "Scrypt" }, - { "1.3.6.1.4.1.25258.1.3", "McEliece" }, - { "1.3.6.1.4.1.25258.1.5", "XMSS-draft6" }, - { "1.3.6.1.4.1.25258.1.6.1", "GOST-34.10-2012-256/EMSA1(SHA-256)" }, - { "1.3.6.1.4.1.25258.1.8", "XMSS" }, - { "1.3.6.1.4.1.25258.3.1", "Serpent/CBC" }, - { "1.3.6.1.4.1.25258.3.101", "Serpent/GCM" }, - { "1.3.6.1.4.1.25258.3.102", "Twofish/GCM" }, - { "1.3.6.1.4.1.25258.3.2", "Threefish-512/CBC" }, - { "1.3.6.1.4.1.25258.3.2.1", "AES-128/OCB" }, - { "1.3.6.1.4.1.25258.3.2.2", "AES-192/OCB" }, - { "1.3.6.1.4.1.25258.3.2.3", "AES-256/OCB" }, - { "1.3.6.1.4.1.25258.3.2.4", "Serpent/OCB" }, - { "1.3.6.1.4.1.25258.3.2.5", "Twofish/OCB" }, - { "1.3.6.1.4.1.25258.3.2.6", "Camellia-128/OCB" }, - { "1.3.6.1.4.1.25258.3.2.7", "Camellia-192/OCB" }, - { "1.3.6.1.4.1.25258.3.2.8", "Camellia-256/OCB" }, - { "1.3.6.1.4.1.25258.3.3", "Twofish/CBC" }, - { "1.3.6.1.4.1.25258.3.4.1", "AES-128/SIV" }, - { "1.3.6.1.4.1.25258.3.4.2", "AES-192/SIV" }, - { "1.3.6.1.4.1.25258.3.4.3", "AES-256/SIV" }, - { "1.3.6.1.4.1.25258.3.4.4", "Serpent/SIV" }, - { "1.3.6.1.4.1.25258.3.4.5", "Twofish/SIV" }, - { "1.3.6.1.4.1.25258.3.4.6", "Camellia-128/SIV" }, - { "1.3.6.1.4.1.25258.3.4.7", "Camellia-192/SIV" }, - { "1.3.6.1.4.1.25258.3.4.8", "Camellia-256/SIV" }, - { "1.3.6.1.4.1.25258.3.4.9", "SM4/SIV" }, - { "1.3.6.1.4.1.3029.1.2.1", "ElGamal" }, - { "1.3.6.1.4.1.3029.1.5.1", "OpenPGP.Curve25519" }, - { "1.3.6.1.4.1.311.20.2.2", "Microsoft SmartcardLogon" }, - { "1.3.6.1.4.1.311.20.2.3", "Microsoft UPN" }, - { "1.3.6.1.4.1.8301.3.1.2.9.0.38", "secp521r1" }, - { "1.3.6.1.5.5.7.1.1", "PKIX.AuthorityInformationAccess" }, - { "1.3.6.1.5.5.7.3.1", "PKIX.ServerAuth" }, - { "1.3.6.1.5.5.7.3.2", "PKIX.ClientAuth" }, - { "1.3.6.1.5.5.7.3.3", "PKIX.CodeSigning" }, - { "1.3.6.1.5.5.7.3.4", "PKIX.EmailProtection" }, - { "1.3.6.1.5.5.7.3.5", "PKIX.IPsecEndSystem" }, - { "1.3.6.1.5.5.7.3.6", "PKIX.IPsecTunnel" }, - { "1.3.6.1.5.5.7.3.7", "PKIX.IPsecUser" }, - { "1.3.6.1.5.5.7.3.8", "PKIX.TimeStamping" }, - { "1.3.6.1.5.5.7.3.9", "PKIX.OCSPSigning" }, - { "1.3.6.1.5.5.7.48.1", "PKIX.OCSP" }, - { "1.3.6.1.5.5.7.48.1.1", "PKIX.OCSP.BasicResponse" }, - { "1.3.6.1.5.5.7.48.2", "PKIX.CertificateAuthorityIssuers" }, - { "1.3.6.1.5.5.7.8.5", "PKIX.XMPPAddr" }, - { "2.16.840.1.101.3.4.1.2", "AES-128/CBC" }, - { "2.16.840.1.101.3.4.1.22", "AES-192/CBC" }, - { "2.16.840.1.101.3.4.1.25", "KeyWrap.AES-192" }, - { "2.16.840.1.101.3.4.1.26", "AES-192/GCM" }, - { "2.16.840.1.101.3.4.1.27", "AES-192/CCM" }, - { "2.16.840.1.101.3.4.1.42", "AES-256/CBC" }, - { "2.16.840.1.101.3.4.1.45", "KeyWrap.AES-256" }, - { "2.16.840.1.101.3.4.1.46", "AES-256/GCM" }, - { "2.16.840.1.101.3.4.1.47", "AES-256/CCM" }, - { "2.16.840.1.101.3.4.1.5", "KeyWrap.AES-128" }, - { "2.16.840.1.101.3.4.1.6", "AES-128/GCM" }, - { "2.16.840.1.101.3.4.1.7", "AES-128/CCM" }, - { "2.16.840.1.101.3.4.2.1", "SHA-256" }, - { "2.16.840.1.101.3.4.2.10", "SHA-3(512)" }, - { "2.16.840.1.101.3.4.2.11", "SHAKE-128" }, - { "2.16.840.1.101.3.4.2.12", "SHAKE-256" }, - { "2.16.840.1.101.3.4.2.2", "SHA-384" }, - { "2.16.840.1.101.3.4.2.3", "SHA-512" }, - { "2.16.840.1.101.3.4.2.4", "SHA-224" }, - { "2.16.840.1.101.3.4.2.6", "SHA-512-256" }, - { "2.16.840.1.101.3.4.2.7", "SHA-3(224)" }, - { "2.16.840.1.101.3.4.2.8", "SHA-3(256)" }, - { "2.16.840.1.101.3.4.2.9", "SHA-3(384)" }, - { "2.16.840.1.101.3.4.3.1", "DSA/EMSA1(SHA-224)" }, - { "2.16.840.1.101.3.4.3.10", "ECDSA/EMSA1(SHA-3(256))" }, - { "2.16.840.1.101.3.4.3.11", "ECDSA/EMSA1(SHA-3(384))" }, - { "2.16.840.1.101.3.4.3.12", "ECDSA/EMSA1(SHA-3(512))" }, - { "2.16.840.1.101.3.4.3.13", "RSA/EMSA3(SHA-3(224))" }, - { "2.16.840.1.101.3.4.3.14", "RSA/EMSA3(SHA-3(256))" }, - { "2.16.840.1.101.3.4.3.15", "RSA/EMSA3(SHA-3(384))" }, - { "2.16.840.1.101.3.4.3.16", "RSA/EMSA3(SHA-3(512))" }, - { "2.16.840.1.101.3.4.3.2", "DSA/EMSA1(SHA-256)" }, - { "2.16.840.1.101.3.4.3.3", "DSA/EMSA1(SHA-384)" }, - { "2.16.840.1.101.3.4.3.4", "DSA/EMSA1(SHA-512)" }, - { "2.16.840.1.101.3.4.3.5", "DSA/EMSA1(SHA-3(224))" }, - { "2.16.840.1.101.3.4.3.6", "DSA/EMSA1(SHA-3(256))" }, - { "2.16.840.1.101.3.4.3.7", "DSA/EMSA1(SHA-3(384))" }, - { "2.16.840.1.101.3.4.3.8", "DSA/EMSA1(SHA-3(512))" }, - { "2.16.840.1.101.3.4.3.9", "ECDSA/EMSA1(SHA-3(224))" }, - { "2.16.840.1.113730.1.13", "Certificate Comment" }, - { "2.5.29.14", "X509v3.SubjectKeyIdentifier" }, - { "2.5.29.15", "X509v3.KeyUsage" }, - { "2.5.29.16", "X509v3.PrivateKeyUsagePeriod" }, - { "2.5.29.17", "X509v3.SubjectAlternativeName" }, - { "2.5.29.18", "X509v3.IssuerAlternativeName" }, - { "2.5.29.19", "X509v3.BasicConstraints" }, - { "2.5.29.20", "X509v3.CRLNumber" }, - { "2.5.29.21", "X509v3.ReasonCode" }, - { "2.5.29.23", "X509v3.HoldInstructionCode" }, - { "2.5.29.24", "X509v3.InvalidityDate" }, - { "2.5.29.28", "X509v3.CRLIssuingDistributionPoint" }, - { "2.5.29.30", "X509v3.NameConstraints" }, - { "2.5.29.31", "X509v3.CRLDistributionPoints" }, - { "2.5.29.32", "X509v3.CertificatePolicies" }, - { "2.5.29.32.0", "X509v3.AnyPolicy" }, - { "2.5.29.35", "X509v3.AuthorityKeyIdentifier" }, - { "2.5.29.36", "X509v3.PolicyConstraints" }, - { "2.5.29.37", "X509v3.ExtendedKeyUsage" }, - { "2.5.4.10", "X520.Organization" }, - { "2.5.4.11", "X520.OrganizationalUnit" }, - { "2.5.4.12", "X520.Title" }, - { "2.5.4.3", "X520.CommonName" }, - { "2.5.4.4", "X520.Surname" }, - { "2.5.4.42", "X520.GivenName" }, - { "2.5.4.43", "X520.Initials" }, - { "2.5.4.44", "X520.GenerationalQualifier" }, - { "2.5.4.46", "X520.DNQualifier" }, - { "2.5.4.5", "X520.SerialNumber" }, - { "2.5.4.6", "X520.Country" }, - { "2.5.4.65", "X520.Pseudonym" }, - { "2.5.4.7", "X520.Locality" }, - { "2.5.4.8", "X520.State" }, - { "2.5.4.9", "X520.StreetAddress" }, - { "2.5.8.1.1", "RSA" } - }; - } - -std::unordered_map OIDS::load_str2oid_map() - { - return std::unordered_map{ - { "AES-128/CBC", OID({2,16,840,1,101,3,4,1,2}) }, - { "AES-128/CCM", OID({2,16,840,1,101,3,4,1,7}) }, - { "AES-128/GCM", OID({2,16,840,1,101,3,4,1,6}) }, - { "AES-128/OCB", OID({1,3,6,1,4,1,25258,3,2,1}) }, - { "AES-128/SIV", OID({1,3,6,1,4,1,25258,3,4,1}) }, - { "AES-192/CBC", OID({2,16,840,1,101,3,4,1,22}) }, - { "AES-192/CCM", OID({2,16,840,1,101,3,4,1,27}) }, - { "AES-192/GCM", OID({2,16,840,1,101,3,4,1,26}) }, - { "AES-192/OCB", OID({1,3,6,1,4,1,25258,3,2,2}) }, - { "AES-192/SIV", OID({1,3,6,1,4,1,25258,3,4,2}) }, - { "AES-256/CBC", OID({2,16,840,1,101,3,4,1,42}) }, - { "AES-256/CCM", OID({2,16,840,1,101,3,4,1,47}) }, - { "AES-256/GCM", OID({2,16,840,1,101,3,4,1,46}) }, - { "AES-256/OCB", OID({1,3,6,1,4,1,25258,3,2,3}) }, - { "AES-256/SIV", OID({1,3,6,1,4,1,25258,3,4,3}) }, - { "CAST-128/CBC", OID({1,2,840,113533,7,66,10}) }, - { "Camellia-128/CBC", OID({1,2,392,200011,61,1,1,1,2}) }, - { "Camellia-128/GCM", OID({0,3,4401,5,3,1,9,6}) }, - { "Camellia-128/OCB", OID({1,3,6,1,4,1,25258,3,2,6}) }, - { "Camellia-128/SIV", OID({1,3,6,1,4,1,25258,3,4,6}) }, - { "Camellia-192/CBC", OID({1,2,392,200011,61,1,1,1,3}) }, - { "Camellia-192/GCM", OID({0,3,4401,5,3,1,9,26}) }, - { "Camellia-192/OCB", OID({1,3,6,1,4,1,25258,3,2,7}) }, - { "Camellia-192/SIV", OID({1,3,6,1,4,1,25258,3,4,7}) }, - { "Camellia-256/CBC", OID({1,2,392,200011,61,1,1,1,4}) }, - { "Camellia-256/GCM", OID({0,3,4401,5,3,1,9,46}) }, - { "Camellia-256/OCB", OID({1,3,6,1,4,1,25258,3,2,8}) }, - { "Camellia-256/SIV", OID({1,3,6,1,4,1,25258,3,4,8}) }, - { "Certificate Comment", OID({2,16,840,1,113730,1,13}) }, - { "ChaCha20Poly1305", OID({1,2,840,113549,1,9,16,3,18}) }, - { "Compression.Zlib", OID({1,2,840,113549,1,9,16,3,8}) }, - { "Curve25519", OID({1,3,101,110}) }, - { "DES/CBC", OID({1,3,14,3,2,7}) }, - { "DH", OID({1,2,840,10046,2,1}) }, - { "DSA", OID({1,2,840,10040,4,1}) }, - { "DSA/EMSA1(SHA-160)", OID({1,2,840,10040,4,3}) }, - { "DSA/EMSA1(SHA-224)", OID({2,16,840,1,101,3,4,3,1}) }, - { "DSA/EMSA1(SHA-256)", OID({2,16,840,1,101,3,4,3,2}) }, - { "DSA/EMSA1(SHA-3(224))", OID({2,16,840,1,101,3,4,3,5}) }, - { "DSA/EMSA1(SHA-3(256))", OID({2,16,840,1,101,3,4,3,6}) }, - { "DSA/EMSA1(SHA-3(384))", OID({2,16,840,1,101,3,4,3,7}) }, - { "DSA/EMSA1(SHA-3(512))", OID({2,16,840,1,101,3,4,3,8}) }, - { "DSA/EMSA1(SHA-384)", OID({2,16,840,1,101,3,4,3,3}) }, - { "DSA/EMSA1(SHA-512)", OID({2,16,840,1,101,3,4,3,4}) }, - { "ECDH", OID({1,3,132,1,12}) }, - { "ECDSA", OID({1,2,840,10045,2,1}) }, - { "ECDSA/EMSA1(SHA-160)", OID({1,2,840,10045,4,1}) }, - { "ECDSA/EMSA1(SHA-224)", OID({1,2,840,10045,4,3,1}) }, - { "ECDSA/EMSA1(SHA-256)", OID({1,2,840,10045,4,3,2}) }, - { "ECDSA/EMSA1(SHA-3(224))", OID({2,16,840,1,101,3,4,3,9}) }, - { "ECDSA/EMSA1(SHA-3(256))", OID({2,16,840,1,101,3,4,3,10}) }, - { "ECDSA/EMSA1(SHA-3(384))", OID({2,16,840,1,101,3,4,3,11}) }, - { "ECDSA/EMSA1(SHA-3(512))", OID({2,16,840,1,101,3,4,3,12}) }, - { "ECDSA/EMSA1(SHA-384)", OID({1,2,840,10045,4,3,3}) }, - { "ECDSA/EMSA1(SHA-512)", OID({1,2,840,10045,4,3,4}) }, - { "ECGDSA", OID({1,3,36,3,3,2,5,2,1}) }, - { "ECGDSA/EMSA1(RIPEMD-160)", OID({1,3,36,3,3,2,5,4,1}) }, - { "ECGDSA/EMSA1(SHA-160)", OID({1,3,36,3,3,2,5,4,2}) }, - { "ECGDSA/EMSA1(SHA-224)", OID({1,3,36,3,3,2,5,4,3}) }, - { "ECGDSA/EMSA1(SHA-256)", OID({1,3,36,3,3,2,5,4,4}) }, - { "ECGDSA/EMSA1(SHA-384)", OID({1,3,36,3,3,2,5,4,5}) }, - { "ECGDSA/EMSA1(SHA-512)", OID({1,3,36,3,3,2,5,4,6}) }, - { "ECKCDSA", OID({1,0,14888,3,0,5}) }, - { "ECKCDSA/EMSA1(SHA-1)", OID({1,2,410,200004,1,100,4,3}) }, - { "ECKCDSA/EMSA1(SHA-224)", OID({1,2,410,200004,1,100,4,4}) }, - { "ECKCDSA/EMSA1(SHA-256)", OID({1,2,410,200004,1,100,4,5}) }, - { "Ed25519", OID({1,3,101,112}) }, - { "ElGamal", OID({1,3,6,1,4,1,3029,1,2,1}) }, - { "GOST-34.10", OID({1,2,643,2,2,19}) }, - { "GOST-34.10-2012-256", OID({1,2,643,7,1,1,1,1}) }, - { "GOST-34.10-2012-256/EMSA1(SHA-256)", OID({1,3,6,1,4,1,25258,1,6,1}) }, - { "GOST-34.10-2012-256/EMSA1(Streebog-256)", OID({1,2,643,7,1,1,3,2}) }, - { "GOST-34.10-2012-512", OID({1,2,643,7,1,1,1,2}) }, - { "GOST-34.10-2012-512/EMSA1(Streebog-512)", OID({1,2,643,7,1,1,3,3}) }, - { "GOST-34.10/EMSA1(GOST-R-34.11-94)", OID({1,2,643,2,2,3}) }, - { "GOST.INN", OID({1,2,643,3,131,1,1}) }, - { "GOST.IssuerSigningTool", OID({1,2,643,100,112}) }, - { "GOST.OGRN", OID({1,2,643,100,1}) }, - { "GOST.SubjectSigningTool", OID({1,2,643,100,111}) }, - { "HMAC(SHA-160)", OID({1,2,840,113549,2,7}) }, - { "HMAC(SHA-224)", OID({1,2,840,113549,2,8}) }, - { "HMAC(SHA-256)", OID({1,2,840,113549,2,9}) }, - { "HMAC(SHA-384)", OID({1,2,840,113549,2,10}) }, - { "HMAC(SHA-512)", OID({1,2,840,113549,2,11}) }, - { "HMAC(SHA-512-256)", OID({1,2,840,113549,2,13}) }, - { "KeyWrap.AES-128", OID({2,16,840,1,101,3,4,1,5}) }, - { "KeyWrap.AES-192", OID({2,16,840,1,101,3,4,1,25}) }, - { "KeyWrap.AES-256", OID({2,16,840,1,101,3,4,1,45}) }, - { "KeyWrap.CAST-128", OID({1,2,840,113533,7,66,15}) }, - { "KeyWrap.TripleDES", OID({1,2,840,113549,1,9,16,3,6}) }, - { "MD5", OID({1,2,840,113549,2,5}) }, - { "MGF1", OID({1,2,840,113549,1,1,8}) }, - { "McEliece", OID({1,3,6,1,4,1,25258,1,3}) }, - { "Microsoft SmartcardLogon", OID({1,3,6,1,4,1,311,20,2,2}) }, - { "Microsoft UPN", OID({1,3,6,1,4,1,311,20,2,3}) }, - { "OpenPGP.Curve25519", OID({1,3,6,1,4,1,3029,1,5,1}) }, - { "OpenPGP.Ed25519", OID({1,3,6,1,4,1,11591,15,1}) }, - { "PBE-PKCS5v20", OID({1,2,840,113549,1,5,13}) }, - { "PBES2", OID({1,2,840,113549,1,5,13}) }, - { "PKCS5.PBKDF2", OID({1,2,840,113549,1,5,12}) }, - { "PKCS9.ChallengePassword", OID({1,2,840,113549,1,9,7}) }, - { "PKCS9.ContentType", OID({1,2,840,113549,1,9,3}) }, - { "PKCS9.EmailAddress", OID({1,2,840,113549,1,9,1}) }, - { "PKCS9.ExtensionRequest", OID({1,2,840,113549,1,9,14}) }, - { "PKCS9.MessageDigest", OID({1,2,840,113549,1,9,4}) }, - { "PKCS9.UnstructuredName", OID({1,2,840,113549,1,9,2}) }, - { "PKIX.AuthorityInformationAccess", OID({1,3,6,1,5,5,7,1,1}) }, - { "PKIX.CertificateAuthorityIssuers", OID({1,3,6,1,5,5,7,48,2}) }, - { "PKIX.ClientAuth", OID({1,3,6,1,5,5,7,3,2}) }, - { "PKIX.CodeSigning", OID({1,3,6,1,5,5,7,3,3}) }, - { "PKIX.EmailProtection", OID({1,3,6,1,5,5,7,3,4}) }, - { "PKIX.IPsecEndSystem", OID({1,3,6,1,5,5,7,3,5}) }, - { "PKIX.IPsecTunnel", OID({1,3,6,1,5,5,7,3,6}) }, - { "PKIX.IPsecUser", OID({1,3,6,1,5,5,7,3,7}) }, - { "PKIX.OCSP", OID({1,3,6,1,5,5,7,48,1}) }, - { "PKIX.OCSP.BasicResponse", OID({1,3,6,1,5,5,7,48,1,1}) }, - { "PKIX.OCSPSigning", OID({1,3,6,1,5,5,7,3,9}) }, - { "PKIX.ServerAuth", OID({1,3,6,1,5,5,7,3,1}) }, - { "PKIX.TimeStamping", OID({1,3,6,1,5,5,7,3,8}) }, - { "PKIX.XMPPAddr", OID({1,3,6,1,5,5,7,8,5}) }, - { "RIPEMD-160", OID({1,3,36,3,2,1}) }, - { "RSA", OID({1,2,840,113549,1,1,1}) }, - { "RSA/EMSA3(MD5)", OID({1,2,840,113549,1,1,4}) }, - { "RSA/EMSA3(RIPEMD-160)", OID({1,3,36,3,3,1,2}) }, - { "RSA/EMSA3(SHA-160)", OID({1,2,840,113549,1,1,5}) }, - { "RSA/EMSA3(SHA-224)", OID({1,2,840,113549,1,1,14}) }, - { "RSA/EMSA3(SHA-256)", OID({1,2,840,113549,1,1,11}) }, - { "RSA/EMSA3(SHA-3(224))", OID({2,16,840,1,101,3,4,3,13}) }, - { "RSA/EMSA3(SHA-3(256))", OID({2,16,840,1,101,3,4,3,14}) }, - { "RSA/EMSA3(SHA-3(384))", OID({2,16,840,1,101,3,4,3,15}) }, - { "RSA/EMSA3(SHA-3(512))", OID({2,16,840,1,101,3,4,3,16}) }, - { "RSA/EMSA3(SHA-384)", OID({1,2,840,113549,1,1,12}) }, - { "RSA/EMSA3(SHA-512)", OID({1,2,840,113549,1,1,13}) }, - { "RSA/EMSA3(SHA-512-256)", OID({1,2,840,113549,1,1,16}) }, - { "RSA/EMSA3(SM3)", OID({1,2,156,10197,1,504}) }, - { "RSA/EMSA4", OID({1,2,840,113549,1,1,10}) }, - { "RSA/OAEP", OID({1,2,840,113549,1,1,7}) }, - { "SEED/CBC", OID({1,2,410,200004,1,4}) }, - { "SHA-160", OID({1,3,14,3,2,26}) }, - { "SHA-224", OID({2,16,840,1,101,3,4,2,4}) }, - { "SHA-256", OID({2,16,840,1,101,3,4,2,1}) }, - { "SHA-3(224)", OID({2,16,840,1,101,3,4,2,7}) }, - { "SHA-3(256)", OID({2,16,840,1,101,3,4,2,8}) }, - { "SHA-3(384)", OID({2,16,840,1,101,3,4,2,9}) }, - { "SHA-3(512)", OID({2,16,840,1,101,3,4,2,10}) }, - { "SHA-384", OID({2,16,840,1,101,3,4,2,2}) }, - { "SHA-512", OID({2,16,840,1,101,3,4,2,3}) }, - { "SHA-512-256", OID({2,16,840,1,101,3,4,2,6}) }, - { "SHAKE-128", OID({2,16,840,1,101,3,4,2,11}) }, - { "SHAKE-256", OID({2,16,840,1,101,3,4,2,12}) }, - { "SM2", OID({1,2,156,10197,1,301,1}) }, - { "SM2_Enc", OID({1,2,156,10197,1,301,3}) }, - { "SM2_Kex", OID({1,2,156,10197,1,301,2}) }, - { "SM2_Sig", OID({1,2,156,10197,1,301,1}) }, - { "SM2_Sig/SM3", OID({1,2,156,10197,1,501}) }, - { "SM3", OID({1,2,156,10197,1,401}) }, - { "SM4/CBC", OID({1,2,156,10197,1,104,2}) }, - { "SM4/GCM", OID({1,2,156,10197,1,104,8}) }, - { "SM4/OCB", OID({1,2,156,10197,1,104,100}) }, - { "SM4/SIV", OID({1,3,6,1,4,1,25258,3,4,9}) }, - { "Scrypt", OID({1,3,6,1,4,1,11591,4,11}) }, - { "Serpent/CBC", OID({1,3,6,1,4,1,25258,3,1}) }, - { "Serpent/GCM", OID({1,3,6,1,4,1,25258,3,101}) }, - { "Serpent/OCB", OID({1,3,6,1,4,1,25258,3,2,4}) }, - { "Serpent/SIV", OID({1,3,6,1,4,1,25258,3,4,4}) }, - { "Streebog-256", OID({1,2,643,7,1,1,2,2}) }, - { "Streebog-512", OID({1,2,643,7,1,1,2,3}) }, - { "Threefish-512/CBC", OID({1,3,6,1,4,1,25258,3,2}) }, - { "Tiger(24,3)", OID({1,3,6,1,4,1,11591,12,2}) }, - { "TripleDES/CBC", OID({1,2,840,113549,3,7}) }, - { "Twofish/CBC", OID({1,3,6,1,4,1,25258,3,3}) }, - { "Twofish/GCM", OID({1,3,6,1,4,1,25258,3,102}) }, - { "Twofish/OCB", OID({1,3,6,1,4,1,25258,3,2,5}) }, - { "Twofish/SIV", OID({1,3,6,1,4,1,25258,3,4,5}) }, - { "X509v3.AnyPolicy", OID({2,5,29,32,0}) }, - { "X509v3.AuthorityKeyIdentifier", OID({2,5,29,35}) }, - { "X509v3.BasicConstraints", OID({2,5,29,19}) }, - { "X509v3.CRLDistributionPoints", OID({2,5,29,31}) }, - { "X509v3.CRLIssuingDistributionPoint", OID({2,5,29,28}) }, - { "X509v3.CRLNumber", OID({2,5,29,20}) }, - { "X509v3.CertificatePolicies", OID({2,5,29,32}) }, - { "X509v3.ExtendedKeyUsage", OID({2,5,29,37}) }, - { "X509v3.HoldInstructionCode", OID({2,5,29,23}) }, - { "X509v3.InvalidityDate", OID({2,5,29,24}) }, - { "X509v3.IssuerAlternativeName", OID({2,5,29,18}) }, - { "X509v3.KeyUsage", OID({2,5,29,15}) }, - { "X509v3.NameConstraints", OID({2,5,29,30}) }, - { "X509v3.PolicyConstraints", OID({2,5,29,36}) }, - { "X509v3.PrivateKeyUsagePeriod", OID({2,5,29,16}) }, - { "X509v3.ReasonCode", OID({2,5,29,21}) }, - { "X509v3.SubjectAlternativeName", OID({2,5,29,17}) }, - { "X509v3.SubjectKeyIdentifier", OID({2,5,29,14}) }, - { "X520.CommonName", OID({2,5,4,3}) }, - { "X520.Country", OID({2,5,4,6}) }, - { "X520.DNQualifier", OID({2,5,4,46}) }, - { "X520.GenerationalQualifier", OID({2,5,4,44}) }, - { "X520.GivenName", OID({2,5,4,42}) }, - { "X520.Initials", OID({2,5,4,43}) }, - { "X520.Locality", OID({2,5,4,7}) }, - { "X520.Organization", OID({2,5,4,10}) }, - { "X520.OrganizationalUnit", OID({2,5,4,11}) }, - { "X520.Pseudonym", OID({2,5,4,65}) }, - { "X520.SerialNumber", OID({2,5,4,5}) }, - { "X520.State", OID({2,5,4,8}) }, - { "X520.StreetAddress", OID({2,5,4,9}) }, - { "X520.Surname", OID({2,5,4,4}) }, - { "X520.Title", OID({2,5,4,12}) }, - { "XMSS", OID({1,3,6,1,4,1,25258,1,8}) }, - { "XMSS-draft6", OID({1,3,6,1,4,1,25258,1,5}) }, - { "brainpool160r1", OID({1,3,36,3,3,2,8,1,1,1}) }, - { "brainpool192r1", OID({1,3,36,3,3,2,8,1,1,3}) }, - { "brainpool224r1", OID({1,3,36,3,3,2,8,1,1,5}) }, - { "brainpool256r1", OID({1,3,36,3,3,2,8,1,1,7}) }, - { "brainpool320r1", OID({1,3,36,3,3,2,8,1,1,9}) }, - { "brainpool384r1", OID({1,3,36,3,3,2,8,1,1,11}) }, - { "brainpool512r1", OID({1,3,36,3,3,2,8,1,1,13}) }, - { "frp256v1", OID({1,2,250,1,223,101,256,1}) }, - { "gost_256A", OID({1,2,643,7,1,2,1,1,1}) }, - { "gost_256B", OID({1,2,643,7,1,2,1,1,2}) }, - { "gost_512A", OID({1,2,643,7,1,2,1,2,1}) }, - { "gost_512B", OID({1,2,643,7,1,2,1,2,2}) }, - { "secp160k1", OID({1,3,132,0,9}) }, - { "secp160r1", OID({1,3,132,0,8}) }, - { "secp160r2", OID({1,3,132,0,30}) }, - { "secp192k1", OID({1,3,132,0,31}) }, - { "secp192r1", OID({1,2,840,10045,3,1,1}) }, - { "secp224k1", OID({1,3,132,0,32}) }, - { "secp224r1", OID({1,3,132,0,33}) }, - { "secp256k1", OID({1,3,132,0,10}) }, - { "secp256r1", OID({1,2,840,10045,3,1,7}) }, - { "secp384r1", OID({1,3,132,0,34}) }, - { "secp521r1", OID({1,3,132,0,35}) }, - { "sm2p256v1", OID({1,2,156,10197,1,301}) }, - { "x962_p192v2", OID({1,2,840,10045,3,1,2}) }, - { "x962_p192v3", OID({1,2,840,10045,3,1,3}) }, - { "x962_p239v1", OID({1,2,840,10045,3,1,4}) }, - { "x962_p239v2", OID({1,2,840,10045,3,1,5}) }, - { "x962_p239v3", OID({1,2,840,10045,3,1,6}) } - }; - } - -} - -/* -* OID Registry -* (C) 1999-2008,2013 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - -namespace Botan { - -namespace { - -class OID_Map final - { +class DataSource_BERObject final : public DataSource { public: - void add_oid(const OID& oid, const std::string& str) - { - add_str2oid(oid, str); - add_oid2str(oid, str); - } + size_t read(uint8_t out[], size_t length) override { + BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); + const size_t got = std::min(m_obj.length() - m_offset, length); + copy_mem(out, m_obj.bits() + m_offset, got); + m_offset += got; + return got; + } - void add_str2oid(const OID& oid, const std::string& str) - { - lock_guard_type lock(m_mutex); - auto i = m_str2oid.find(str); - if(i == m_str2oid.end()) - m_str2oid.insert(std::make_pair(str, oid)); - } + size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override { + BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); + const size_t bytes_left = m_obj.length() - m_offset; - void add_oid2str(const OID& oid, const std::string& str) - { - const std::string oid_str = oid.to_string(); - lock_guard_type lock(m_mutex); - auto i = m_oid2str.find(oid_str); - if(i == m_oid2str.end()) - m_oid2str.insert(std::make_pair(oid_str, str)); - } + if (peek_offset >= bytes_left) return 0; - std::string oid2str(const OID& oid) - { - const std::string oid_str = oid.to_string(); + const size_t got = std::min(bytes_left - peek_offset, length); + copy_mem(out, m_obj.bits() + peek_offset, got); + return got; + } - lock_guard_type lock(m_mutex); + bool check_available(size_t n) override { + BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); + return (n <= (m_obj.length() - m_offset)); + } - auto i = m_oid2str.find(oid_str); - if(i != m_oid2str.end()) - return i->second; + bool end_of_data() const override { return get_bytes_read() == m_obj.length(); } - return ""; - } + size_t get_bytes_read() const override { return m_offset; } - OID str2oid(const std::string& str) - { - lock_guard_type lock(m_mutex); - auto i = m_str2oid.find(str); - if(i != m_str2oid.end()) - return i->second; - - return OID(); - } - - bool have_oid(const std::string& str) - { - lock_guard_type lock(m_mutex); - return m_str2oid.find(str) != m_str2oid.end(); - } - - static OID_Map& global_registry() - { - static OID_Map g_map; - return g_map; - } + explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)), m_offset(0) {} private: + BER_Object m_obj; + size_t m_offset; +}; - OID_Map() - { - m_str2oid = OIDS::load_str2oid_map(); - m_oid2str = OIDS::load_oid2str_map(); - } - - mutex_type m_mutex; - std::unordered_map m_str2oid; - std::unordered_map m_oid2str; - }; - -} - -void OIDS::add_oid(const OID& oid, const std::string& name) - { - OID_Map::global_registry().add_oid(oid, name); - } - -void OIDS::add_oidstr(const char* oidstr, const char* name) - { - add_oid(OID(oidstr), name); - } - -void OIDS::add_oid2str(const OID& oid, const std::string& name) - { - OID_Map::global_registry().add_oid2str(oid, name); - } - -void OIDS::add_str2oid(const OID& oid, const std::string& name) - { - OID_Map::global_registry().add_str2oid(oid, name); - } - -std::string OIDS::oid2str_or_empty(const OID& oid) - { - return OID_Map::global_registry().oid2str(oid); - } - -OID OIDS::str2oid_or_empty(const std::string& name) - { - return OID_Map::global_registry().str2oid(name); - } - -std::string OIDS::oid2str_or_throw(const OID& oid) - { - const std::string s = OIDS::oid2str_or_empty(oid); - if(s.empty()) - throw Lookup_Error("No name associated with OID " + oid.to_string()); - return s; - } - -bool OIDS::have_oid(const std::string& name) - { - return OID_Map::global_registry().have_oid(name); - } - -} -/* -* (C) 2019 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - -namespace Botan { - -void Buffered_Computation::update_be(uint16_t val) - { - uint8_t inb[sizeof(val)]; - store_be(val, inb); - add_data(inb, sizeof(inb)); - } - -void Buffered_Computation::update_be(uint32_t val) - { - uint8_t inb[sizeof(val)]; - store_be(val, inb); - add_data(inb, sizeof(inb)); - } - -void Buffered_Computation::update_be(uint64_t val) - { - uint8_t inb[sizeof(val)]; - store_be(val, inb); - add_data(inb, sizeof(inb)); - } - -void Buffered_Computation::update_le(uint16_t val) - { - uint8_t inb[sizeof(val)]; - store_le(val, inb); - add_data(inb, sizeof(inb)); - } - -void Buffered_Computation::update_le(uint32_t val) - { - uint8_t inb[sizeof(val)]; - store_le(val, inb); - add_data(inb, sizeof(inb)); - } - -void Buffered_Computation::update_le(uint64_t val) - { - uint8_t inb[sizeof(val)]; - store_le(val, inb); - add_data(inb, sizeof(inb)); - } - -} -/* -* SCAN Name Abstraction -* (C) 2008-2009,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - -namespace Botan { - -namespace { - -std::string make_arg(const std::vector>& name, size_t start) - { - std::string output = name[start].second; - size_t level = name[start].first; - - size_t paren_depth = 0; - - for(size_t i = start + 1; i != name.size(); ++i) - { - if(name[i].first <= name[start].first) - break; - - if(name[i].first > level) - { - output += "(" + name[i].second; - ++paren_depth; - } - else if(name[i].first < level) - { - output += ")," + name[i].second; - --paren_depth; - } - else - { - if(output[output.size() - 1] != '(') - output += ","; - output += name[i].second; - } - - level = name[i].first; - } - - for(size_t i = 0; i != paren_depth; ++i) - output += ")"; - - return output; - } - -} - -SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec)) - { - } - -SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info() - { - if(algo_spec.size() == 0) - throw Invalid_Argument("Expected algorithm name, got empty string"); - - std::vector> name; - size_t level = 0; - std::pair accum = std::make_pair(level, ""); - - const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': "; - - for(size_t i = 0; i != algo_spec.size(); ++i) - { - char c = algo_spec[i]; - - if(c == '/' || c == ',' || c == '(' || c == ')') - { - if(c == '(') - ++level; - else if(c == ')') - { - if(level == 0) - throw Decoding_Error(decoding_error + "Mismatched parens"); - --level; - } - - if(c == '/' && level > 0) - accum.second.push_back(c); - else - { - if(accum.second != "") - name.push_back(accum); - accum = std::make_pair(level, ""); - } - } - else - accum.second.push_back(c); - } - - if(accum.second != "") - name.push_back(accum); - - if(level != 0) - throw Decoding_Error(decoding_error + "Missing close paren"); - - if(name.size() == 0) - throw Decoding_Error(decoding_error + "Empty name"); - - m_alg_name = name[0].second; - - bool in_modes = false; - - for(size_t i = 1; i != name.size(); ++i) - { - if(name[i].first == 0) - { - m_mode_info.push_back(make_arg(name, i)); - in_modes = true; - } - else if(name[i].first == 1 && !in_modes) - m_args.push_back(make_arg(name, i)); - } - } - -std::string SCAN_Name::arg(size_t i) const - { - if(i >= arg_count()) - throw Invalid_Argument("SCAN_Name::arg " + std::to_string(i) + - " out of range for '" + to_string() + "'"); - return m_args[i]; - } - -std::string SCAN_Name::arg(size_t i, const std::string& def_value) const - { - if(i >= arg_count()) - return def_value; - return m_args[i]; - } - -size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const - { - if(i >= arg_count()) - return def_value; - return to_u32bit(m_args[i]); - } - -} -/* -* (C) 2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - -namespace Botan { - -void SymmetricAlgorithm::throw_key_not_set_error() const - { - throw Key_Not_Set(name()); - } - -void SymmetricAlgorithm::set_key(const uint8_t key[], size_t length) - { - if(!valid_keylength(length)) - throw Invalid_Key_Length(name(), length); - key_schedule(key, length); - } - -} -/* -* OctetString -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - -namespace Botan { +} // namespace /* -* Create an OctetString from RNG output -*/ -OctetString::OctetString(RandomNumberGenerator& rng, - size_t len) - { - rng.random_vec(m_data, len); - } - -/* -* Create an OctetString from a hex string -*/ -OctetString::OctetString(const std::string& hex_string) - { - if(!hex_string.empty()) - { - m_data.resize(1 + hex_string.length() / 2); - m_data.resize(hex_decode(m_data.data(), hex_string)); - } - } - -/* -* Create an OctetString from a byte string -*/ -OctetString::OctetString(const uint8_t in[], size_t n) - { - m_data.assign(in, in + n); - } - -/* -* Set the parity of each key byte to odd -*/ -void OctetString::set_odd_parity() - { - const uint8_t ODD_PARITY[256] = { - 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, 0x08, 0x08, 0x0B, 0x0B, - 0x0D, 0x0D, 0x0E, 0x0E, 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16, - 0x19, 0x19, 0x1A, 0x1A, 0x1C, 0x1C, 0x1F, 0x1F, 0x20, 0x20, 0x23, 0x23, - 0x25, 0x25, 0x26, 0x26, 0x29, 0x29, 0x2A, 0x2A, 0x2C, 0x2C, 0x2F, 0x2F, - 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, 0x38, 0x38, 0x3B, 0x3B, - 0x3D, 0x3D, 0x3E, 0x3E, 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46, - 0x49, 0x49, 0x4A, 0x4A, 0x4C, 0x4C, 0x4F, 0x4F, 0x51, 0x51, 0x52, 0x52, - 0x54, 0x54, 0x57, 0x57, 0x58, 0x58, 0x5B, 0x5B, 0x5D, 0x5D, 0x5E, 0x5E, - 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, 0x68, 0x68, 0x6B, 0x6B, - 0x6D, 0x6D, 0x6E, 0x6E, 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76, - 0x79, 0x79, 0x7A, 0x7A, 0x7C, 0x7C, 0x7F, 0x7F, 0x80, 0x80, 0x83, 0x83, - 0x85, 0x85, 0x86, 0x86, 0x89, 0x89, 0x8A, 0x8A, 0x8C, 0x8C, 0x8F, 0x8F, - 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97, 0x98, 0x98, 0x9B, 0x9B, - 0x9D, 0x9D, 0x9E, 0x9E, 0xA1, 0xA1, 0xA2, 0xA2, 0xA4, 0xA4, 0xA7, 0xA7, - 0xA8, 0xA8, 0xAB, 0xAB, 0xAD, 0xAD, 0xAE, 0xAE, 0xB0, 0xB0, 0xB3, 0xB3, - 0xB5, 0xB5, 0xB6, 0xB6, 0xB9, 0xB9, 0xBA, 0xBA, 0xBC, 0xBC, 0xBF, 0xBF, - 0xC1, 0xC1, 0xC2, 0xC2, 0xC4, 0xC4, 0xC7, 0xC7, 0xC8, 0xC8, 0xCB, 0xCB, - 0xCD, 0xCD, 0xCE, 0xCE, 0xD0, 0xD0, 0xD3, 0xD3, 0xD5, 0xD5, 0xD6, 0xD6, - 0xD9, 0xD9, 0xDA, 0xDA, 0xDC, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE3, 0xE3, - 0xE5, 0xE5, 0xE6, 0xE6, 0xE9, 0xE9, 0xEA, 0xEA, 0xEC, 0xEC, 0xEF, 0xEF, - 0xF1, 0xF1, 0xF2, 0xF2, 0xF4, 0xF4, 0xF7, 0xF7, 0xF8, 0xF8, 0xFB, 0xFB, - 0xFD, 0xFD, 0xFE, 0xFE }; - - for(size_t j = 0; j != m_data.size(); ++j) - m_data[j] = ODD_PARITY[m_data[j]]; - } - -/* -* Hex encode an OctetString -*/ -std::string OctetString::to_string() const - { - return hex_encode(m_data.data(), m_data.size()); - } - -/* -* XOR Operation for OctetStrings -*/ -OctetString& OctetString::operator^=(const OctetString& k) - { - if(&k == this) { zeroise(m_data); return (*this); } - xor_buf(m_data.data(), k.begin(), std::min(length(), k.length())); - return (*this); - } - -/* -* Equality Operation for OctetStrings -*/ -bool operator==(const OctetString& s1, const OctetString& s2) - { - return (s1.bits_of() == s2.bits_of()); - } - -/* -* Unequality Operation for OctetStrings -*/ -bool operator!=(const OctetString& s1, const OctetString& s2) - { - return !(s1 == s2); - } - -/* -* Append Operation for OctetStrings -*/ -OctetString operator+(const OctetString& k1, const OctetString& k2) - { - secure_vector out; - out += k1.bits_of(); - out += k2.bits_of(); - return OctetString(out); - } - -/* -* XOR Operation for OctetStrings -*/ -OctetString operator^(const OctetString& k1, const OctetString& k2) - { - secure_vector out(std::max(k1.length(), k2.length())); - - copy_mem(out.data(), k1.begin(), k1.length()); - xor_buf(out.data(), k2.begin(), k2.length()); - return OctetString(out); - } - -} -/* -* Base64 Encoding and Decoding -* (C) 2010,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - -namespace Botan { - -namespace { - -class Base64 final - { - public: - static inline std::string name() noexcept - { - return "base64"; - } - - static inline size_t encoding_bytes_in() noexcept - { - return m_encoding_bytes_in; - } - static inline size_t encoding_bytes_out() noexcept - { - return m_encoding_bytes_out; - } - - static inline size_t decoding_bytes_in() noexcept - { - return m_encoding_bytes_out; - } - static inline size_t decoding_bytes_out() noexcept - { - return m_encoding_bytes_in; - } - - static inline size_t bits_consumed() noexcept - { - return m_encoding_bits; - } - static inline size_t remaining_bits_before_padding() noexcept - { - return m_remaining_bits_before_padding; - } - - static inline size_t encode_max_output(size_t input_length) - { - return (round_up(input_length, m_encoding_bytes_in) / m_encoding_bytes_in) * m_encoding_bytes_out; - } - static inline size_t decode_max_output(size_t input_length) - { - return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out; - } - - static void encode(char out[8], const uint8_t in[5]) noexcept - { - out[0] = Base64::m_bin_to_base64[(in[0] & 0xFC) >> 2]; - out[1] = Base64::m_bin_to_base64[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - out[2] = Base64::m_bin_to_base64[((in[1] & 0x0F) << 2) | (in[2] >> 6)]; - out[3] = Base64::m_bin_to_base64[in[2] & 0x3F]; - } - - static inline uint8_t lookup_binary_value(char input) noexcept - { - return Base64::m_base64_to_bin[static_cast(input)]; - } - - static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws) - { - if(bin <= 0x3F) - { - return true; - } - else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws))) - { - std::string bad_char(1, input); - if(bad_char == "\t") - { bad_char = "\\t"; } - else if(bad_char == "\n") - { bad_char = "\\n"; } - else if(bad_char == "\r") - { bad_char = "\\r"; } - - throw Invalid_Argument( - std::string("base64_decode: invalid base64 character '") + - bad_char + "'"); - } - return false; - } - - static void decode(uint8_t* out_ptr, const uint8_t decode_buf[4]) - { - out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4); - out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2); - out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3]; - } - - static inline size_t bytes_to_remove(size_t final_truncate) - { - return final_truncate; - } - - private: - static const size_t m_encoding_bits = 6; - static const size_t m_remaining_bits_before_padding = 8; - - - static const size_t m_encoding_bytes_in = 3; - static const size_t m_encoding_bytes_out = 4; - - - static const uint8_t m_bin_to_base64[64]; - static const uint8_t m_base64_to_bin[256]; - }; - -const uint8_t Base64::m_bin_to_base64[64] = - { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' - }; - -/* -* base64 Decoder Lookup Table -* Warning: assumes ASCII encodings -*/ -const uint8_t Base64::m_base64_to_bin[256] = - { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, - 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, - 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, - 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, - 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - }; -} - -size_t base64_encode(char out[], - const uint8_t in[], - size_t input_length, - size_t& input_consumed, - bool final_inputs) - { - return base_encode(Base64(), out, in, input_length, input_consumed, final_inputs); - } - -std::string base64_encode(const uint8_t input[], - size_t input_length) - { - return base_encode_to_string(Base64(), input, input_length); - } - -size_t base64_decode(uint8_t out[], - const char in[], - size_t input_length, - size_t& input_consumed, - bool final_inputs, - bool ignore_ws) - { - return base_decode(Base64(), out, in, input_length, input_consumed, final_inputs, ignore_ws); - } - -size_t base64_decode(uint8_t output[], - const char input[], - size_t input_length, - bool ignore_ws) - { - return base_decode_full(Base64(), output, input, input_length, ignore_ws); - } - -size_t base64_decode(uint8_t output[], - const std::string& input, - bool ignore_ws) - { - return base64_decode(output, input.data(), input.length(), ignore_ws); - } - -secure_vector base64_decode(const char input[], - size_t input_length, - bool ignore_ws) - { - return base_decode_to_vec>(Base64(), input, input_length, ignore_ws); - } - -secure_vector base64_decode(const std::string& input, - bool ignore_ws) - { - return base64_decode(input.data(), input.size(), ignore_ws); - } - -size_t base64_encode_max_output(size_t input_length) - { - return Base64::encode_max_output(input_length); - } - -size_t base64_decode_max_output(size_t input_length) - { - return Base64::decode_max_output(input_length); - } - -} -/* -* BigInt Encoding/Decoding -* (C) 1999-2010,2012,2019 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - -namespace Botan { - -std::string BigInt::to_dec_string() const - { - BigInt copy = *this; - copy.set_sign(Positive); - - uint8_t remainder; - std::vector digits; - - while(copy > 0) - { - ct_divide_u8(copy, 10, copy, remainder); - digits.push_back(remainder); - } - - std::string s; - - for(auto i = digits.rbegin(); i != digits.rend(); ++i) - { - s.push_back(Charset::digit2char(*i)); - } - - if(s.empty()) - s += "0"; - - return s; - } - -std::string BigInt::to_hex_string() const - { - const std::vector bits = BigInt::encode(*this); - if(bits.empty()) - return "00"; - else - return hex_encode(bits); - } - -/* -* Encode a BigInt -*/ -void BigInt::encode(uint8_t output[], const BigInt& n, Base base) - { - secure_vector enc = n.encode_locked(base); - copy_mem(output, enc.data(), enc.size()); - } - -namespace { - -std::vector str_to_vector(const std::string& s) - { - std::vector v(s.size()); - std::memcpy(v.data(), s.data(), s.size()); - return v; - } - -secure_vector str_to_lvector(const std::string& s) - { - secure_vector v(s.size()); - std::memcpy(v.data(), s.data(), s.size()); - return v; - } - + * Check if more objects are there + */ +bool BER_Decoder::more_items() const { + if (m_source->end_of_data() && !m_pushed.is_set()) return false; + return true; } /* -* Encode a BigInt -*/ -std::vector BigInt::encode(const BigInt& n, Base base) - { - if(base == Binary) - return BigInt::encode(n); - else if(base == Hexadecimal) - return str_to_vector(n.to_hex_string()); - else if(base == Decimal) - return str_to_vector(n.to_dec_string()); - else - throw Invalid_Argument("Unknown BigInt encoding base"); - } + * Verify that no bytes remain in the source + */ +BER_Decoder& BER_Decoder::verify_end() { + return verify_end("BER_Decoder::verify_end called, but data remains"); +} /* -* Encode a BigInt -*/ -secure_vector BigInt::encode_locked(const BigInt& n, Base base) - { - if(base == Binary) - return BigInt::encode_locked(n); - else if(base == Hexadecimal) - return str_to_lvector(n.to_hex_string()); - else if(base == Decimal) - return str_to_lvector(n.to_dec_string()); - else - throw Invalid_Argument("Unknown BigInt encoding base"); - } + * Verify that no bytes remain in the source + */ +BER_Decoder& BER_Decoder::verify_end(const std::string& err) { + if (!m_source->end_of_data() || m_pushed.is_set()) throw Decoding_Error(err); + return (*this); +} /* -* Encode a BigInt, with leading 0s if needed -*/ -secure_vector BigInt::encode_1363(const BigInt& n, size_t bytes) - { - if(n.bytes() > bytes) - throw Encoding_Error("encode_1363: n is too large to encode properly"); - - secure_vector output(bytes); - n.binary_encode(output.data(), output.size()); - return output; - } - -//static -void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n) - { - if(n.bytes() > bytes) - throw Encoding_Error("encode_1363: n is too large to encode properly"); - - n.binary_encode(output, bytes); - } + * Discard all the bytes remaining in the source + */ +BER_Decoder& BER_Decoder::discard_remaining() { + uint8_t buf; + while (m_source->read_byte(buf)) { + } + return (*this); +} /* -* Encode two BigInt, with leading 0s if needed, and concatenate -*/ -secure_vector BigInt::encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes) - { - if(n1.bytes() > bytes || n2.bytes() > bytes) - throw Encoding_Error("encode_fixed_length_int_pair: values too large to encode properly"); - secure_vector output(2 * bytes); - n1.binary_encode(output.data() , bytes); - n2.binary_encode(output.data() + bytes, bytes); - return output; - } + * Return the BER encoding of the next object + */ +BER_Object BER_Decoder::get_next_object() { + BER_Object next; -/* -* Decode a BigInt -*/ -BigInt BigInt::decode(const uint8_t buf[], size_t length, Base base) - { - BigInt r; - if(base == Binary) - { - r.binary_decode(buf, length); - } - else if(base == Hexadecimal) - { - secure_vector binary; + if (m_pushed.is_set()) { + std::swap(next, m_pushed); + return next; + } - if(length % 2) - { - // Handle lack of leading 0 - const char buf0_with_leading_0[2] = - { '0', static_cast(buf[0]) }; + for (;;) { + ASN1_Tag type_tag, class_tag; + decode_tag(m_source, type_tag, class_tag); + next.set_tagging(type_tag, class_tag); + if (next.is_set() == false) // no more objects + return next; - binary = hex_decode_locked(buf0_with_leading_0, 2); + size_t field_size; + const size_t length = decode_length(m_source, field_size, ALLOWED_EOC_NESTINGS); + if (!m_source->check_available(length)) throw BER_Decoding_Error("Value truncated"); - binary += hex_decode_locked(cast_uint8_ptr_to_char(&buf[1]), - length - 1, - false); - } - else - binary = hex_decode_locked(cast_uint8_ptr_to_char(buf), - length, false); + uint8_t* out = next.mutable_bits(length); + if (m_source->read(out, length) != length) throw BER_Decoding_Error("Value truncated"); - r.binary_decode(binary.data(), binary.size()); - } - else if(base == Decimal) - { - for(size_t i = 0; i != length; ++i) - { - if(Charset::is_space(buf[i])) + if (next.tagging() == EOC) continue; + else + break; + } - if(!Charset::is_digit(buf[i])) - throw Invalid_Argument("BigInt::decode: " - "Invalid character in decimal input"); - - const uint8_t x = Charset::char2digit(buf[i]); - - if(x >= 10) - throw Invalid_Argument("BigInt: Invalid decimal string"); - - r *= 10; - r += x; - } - } - else - throw Invalid_Argument("Unknown BigInt decoding method"); - return r; - } - + return next; } + /* -* BigInt Input/Output -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Push a object back into the stream + */ +void BER_Decoder::push_back(const BER_Object& obj) { + if (m_pushed.is_set()) throw Invalid_State("BER_Decoder: Only one push back is allowed"); + m_pushed = obj; +} + +void BER_Decoder::push_back(BER_Object&& obj) { + if (m_pushed.is_set()) throw Invalid_State("BER_Decoder: Only one push back is allowed"); + m_pushed = std::move(obj); +} + +BER_Decoder BER_Decoder::start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag) { + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, ASN1_Tag(class_tag | CONSTRUCTED)); + return BER_Decoder(std::move(obj), this); +} + +/* + * Finish decoding a CONSTRUCTED type + */ +BER_Decoder& BER_Decoder::end_cons() { + if (!m_parent) throw Invalid_State("BER_Decoder::end_cons called with null parent"); + if (!m_source->end_of_data()) + throw Decoding_Error("BER_Decoder::end_cons called with data left"); + return (*m_parent); +} + +BER_Decoder::BER_Decoder(BER_Object&& obj, BER_Decoder* parent) { + m_data_src.reset(new DataSource_BERObject(std::move(obj))); + m_source = m_data_src.get(); + m_parent = parent; +} + +/* + * BER_Decoder Constructor + */ +BER_Decoder::BER_Decoder(DataSource& src) { m_source = &src; } + +/* + * BER_Decoder Constructor + */ +BER_Decoder::BER_Decoder(const uint8_t data[], size_t length) { + m_data_src.reset(new DataSource_Memory(data, length)); + m_source = m_data_src.get(); +} + +/* + * BER_Decoder Constructor + */ +BER_Decoder::BER_Decoder(const secure_vector& data) { + m_data_src.reset(new DataSource_Memory(data)); + m_source = m_data_src.get(); +} + +/* + * BER_Decoder Constructor + */ +BER_Decoder::BER_Decoder(const std::vector& data) { + m_data_src.reset(new DataSource_Memory(data.data(), data.size())); + m_source = m_data_src.get(); +} + +/* + * BER_Decoder Copy Constructor + */ +BER_Decoder::BER_Decoder(const BER_Decoder& other) { + m_source = other.m_source; + + // take ownership + std::swap(m_data_src, other.m_data_src); + m_parent = other.m_parent; +} + +/* + * Request for an object to decode itself + */ +BER_Decoder& BER_Decoder::decode(ASN1_Object& obj, ASN1_Tag, ASN1_Tag) { + obj.decode_from(*this); + return (*this); +} + +/* + * Decode a BER encoded NULL + */ +BER_Decoder& BER_Decoder::decode_null() { + BER_Object obj = get_next_object(); + obj.assert_is_a(NULL_TAG, UNIVERSAL); + if (obj.length() > 0) throw BER_Decoding_Error("NULL object had nonzero size"); + return (*this); +} + +BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) { + secure_vector out_vec; + decode(out_vec, OCTET_STRING); + out = BigInt::decode(out_vec.data(), out_vec.size()); + return (*this); +} + +/* + * Decode a BER encoded BOOLEAN + */ +BER_Decoder& BER_Decoder::decode(bool& out, ASN1_Tag type_tag, ASN1_Tag class_tag) { + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, class_tag); + + if (obj.length() != 1) throw BER_Decoding_Error("BER boolean value had invalid size"); + + out = (obj.bits()[0]) ? true : false; + return (*this); +} + +/* + * Decode a small BER encoded INTEGER + */ +BER_Decoder& BER_Decoder::decode(size_t& out, ASN1_Tag type_tag, ASN1_Tag class_tag) { + BigInt integer; + decode(integer, type_tag, class_tag); + + if (integer.is_negative()) throw BER_Decoding_Error("Decoded small integer value was negative"); + + if (integer.bits() > 32) throw BER_Decoding_Error("Decoded integer value larger than expected"); + + out = 0; + for (size_t i = 0; i != 4; ++i) out = (out << 8) | integer.byte_at(3 - i); + + return (*this); +} + +/* + * Decode a small BER encoded INTEGER + */ +uint64_t BER_Decoder::decode_constrained_integer(ASN1_Tag type_tag, ASN1_Tag class_tag, + size_t T_bytes) { + if (T_bytes > 8) throw BER_Decoding_Error("Can't decode small integer over 8 bytes"); + + BigInt integer; + decode(integer, type_tag, class_tag); + + if (integer.bits() > 8 * T_bytes) + throw BER_Decoding_Error("Decoded integer value larger than expected"); + + uint64_t out = 0; + for (size_t i = 0; i != 8; ++i) out = (out << 8) | integer.byte_at(7 - i); + + return out; +} + +/* + * Decode a BER encoded INTEGER + */ +BER_Decoder& BER_Decoder::decode(BigInt& out, ASN1_Tag type_tag, ASN1_Tag class_tag) { + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, class_tag); + + if (obj.length() == 0) { + out = 0; + } else { + const bool negative = (obj.bits()[0] & 0x80) ? true : false; + + if (negative) { + secure_vector vec(obj.bits(), obj.bits() + obj.length()); + for (size_t i = obj.length(); i > 0; --i) + if (vec[i - 1]--) break; + for (size_t i = 0; i != obj.length(); ++i) vec[i] = ~vec[i]; + out = BigInt(vec.data(), vec.size()); + out.flip_sign(); + } else { + out = BigInt(obj.bits(), obj.length()); + } + } + + return (*this); +} + +namespace { + +template +void asn1_decode_binary_string(std::vector& buffer, const BER_Object& obj, + ASN1_Tag real_type, ASN1_Tag type_tag, ASN1_Tag class_tag) { + obj.assert_is_a(type_tag, class_tag); + + if (real_type == OCTET_STRING) { + buffer.assign(obj.bits(), obj.bits() + obj.length()); + } else { + if (obj.length() == 0) throw BER_Decoding_Error("Invalid BIT STRING"); + if (obj.bits()[0] >= 8) throw BER_Decoding_Error("Bad number of unused bits in BIT STRING"); + + buffer.resize(obj.length() - 1); + + if (obj.length() > 1) copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1); + } +} + +} // namespace + +/* + * BER decode a BIT STRING or OCTET STRING + */ +BER_Decoder& BER_Decoder::decode(secure_vector& buffer, ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) { + if (real_type != OCTET_STRING && real_type != BIT_STRING) + throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type); + + asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag); + return (*this); +} + +BER_Decoder& BER_Decoder::decode(std::vector& buffer, ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) { + if (real_type != OCTET_STRING && real_type != BIT_STRING) + throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type); + + asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag); + return (*this); +} + +} // namespace Botan +/* + * DER Encoder + * (C) 1999-2007,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +namespace { + +/* + * DER encode an ASN.1 type tag + */ +void encode_tag(std::vector& encoded_tag, ASN1_Tag type_tag, ASN1_Tag class_tag) { + if ((class_tag | 0xE0) != 0xE0) + throw Encoding_Error("DER_Encoder: Invalid class tag " + std::to_string(class_tag)); + + if (type_tag <= 30) { + encoded_tag.push_back(static_cast(type_tag | class_tag)); + } else { + size_t blocks = high_bit(static_cast(type_tag)) + 6; + blocks = (blocks - (blocks % 7)) / 7; + + BOTAN_ASSERT_NOMSG(blocks > 0); + + encoded_tag.push_back(static_cast(class_tag | 0x1F)); + for (size_t i = 0; i != blocks - 1; ++i) + encoded_tag.push_back(0x80 | ((type_tag >> 7 * (blocks - i - 1)) & 0x7F)); + encoded_tag.push_back(type_tag & 0x7F); + } +} + +/* + * DER encode an ASN.1 length field + */ +void encode_length(std::vector& encoded_length, size_t length) { + if (length <= 127) { + encoded_length.push_back(static_cast(length)); + } else { + const size_t bytes_needed = significant_bytes(length); + + encoded_length.push_back(static_cast(0x80 | bytes_needed)); + + for (size_t i = sizeof(length) - bytes_needed; i < sizeof(length); ++i) + encoded_length.push_back(get_byte(i, length)); + } +} + +} // namespace + +DER_Encoder::DER_Encoder(secure_vector& vec) { + m_append_output = [&vec](const uint8_t b[], size_t l) { vec.insert(vec.end(), b, b + l); }; +} + +DER_Encoder::DER_Encoder(std::vector& vec) { + m_append_output = [&vec](const uint8_t b[], size_t l) { vec.insert(vec.end(), b, b + l); }; +} + +/* + * Push the encoded SEQUENCE/SET to the encoder stream + */ +void DER_Encoder::DER_Sequence::push_contents(DER_Encoder& der) { + const ASN1_Tag real_class_tag = ASN1_Tag(m_class_tag | CONSTRUCTED); + + if (m_type_tag == SET) { + std::sort(m_set_contents.begin(), m_set_contents.end()); + for (size_t i = 0; i != m_set_contents.size(); ++i) m_contents += m_set_contents[i]; + m_set_contents.clear(); + } + + der.add_object(m_type_tag, real_class_tag, m_contents.data(), m_contents.size()); + m_contents.clear(); +} + +/* + * Add an encoded value to the SEQUENCE/SET + */ +void DER_Encoder::DER_Sequence::add_bytes(const uint8_t data[], size_t length) { + if (m_type_tag == SET) + m_set_contents.push_back(secure_vector(data, data + length)); + else + m_contents += std::make_pair(data, length); +} + +void DER_Encoder::DER_Sequence::add_bytes(const uint8_t hdr[], size_t hdr_len, const uint8_t val[], + size_t val_len) { + if (m_type_tag == SET) { + secure_vector m; + m.reserve(hdr_len + val_len); + m += std::make_pair(hdr, hdr_len); + m += std::make_pair(val, val_len); + m_set_contents.push_back(std::move(m)); + } else { + m_contents += std::make_pair(hdr, hdr_len); + m_contents += std::make_pair(val, val_len); + } +} + +/* + * Return the type and class taggings + */ +ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const { return ASN1_Tag(m_type_tag | m_class_tag); } + +/* + * DER_Sequence Constructor + */ +DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) + : m_type_tag(t1), m_class_tag(t2) {} + +/* + * Return the encoded contents + */ +secure_vector DER_Encoder::get_contents() { + if (m_subsequences.size() != 0) + throw Invalid_State("DER_Encoder: Sequence hasn't been marked done"); + + if (m_append_output) + throw Invalid_State("DER_Encoder Cannot get contents when using output vector"); + + secure_vector output; + std::swap(output, m_default_outbuf); + return output; +} + +std::vector DER_Encoder::get_contents_unlocked() { + if (m_subsequences.size() != 0) + throw Invalid_State("DER_Encoder: Sequence hasn't been marked done"); + + if (m_append_output) + throw Invalid_State("DER_Encoder Cannot get contents when using output vector"); + + std::vector output(m_default_outbuf.begin(), m_default_outbuf.end()); + m_default_outbuf.clear(); + return output; +} + +/* + * Start a new ASN.1 SEQUENCE/SET/EXPLICIT + */ +DER_Encoder& DER_Encoder::start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag) { + m_subsequences.push_back(DER_Sequence(type_tag, class_tag)); + return (*this); +} + +/* + * Finish the current ASN.1 SEQUENCE/SET/EXPLICIT + */ +DER_Encoder& DER_Encoder::end_cons() { + if (m_subsequences.empty()) throw Invalid_State("DER_Encoder::end_cons: No such sequence"); + + DER_Sequence last_seq = std::move(m_subsequences[m_subsequences.size() - 1]); + m_subsequences.pop_back(); + last_seq.push_contents(*this); + + return (*this); +} + +/* + * Start a new ASN.1 EXPLICIT encoding + */ +DER_Encoder& DER_Encoder::start_explicit(uint16_t type_no) { + ASN1_Tag type_tag = static_cast(type_no); + + // This would confuse DER_Sequence + if (type_tag == SET) throw Internal_Error("DER_Encoder.start_explicit(SET) not supported"); + + return start_cons(type_tag, CONTEXT_SPECIFIC); +} + +/* + * Finish the current ASN.1 EXPLICIT encoding + */ +DER_Encoder& DER_Encoder::end_explicit() { return end_cons(); } + +/* + * Write raw bytes into the stream + */ +DER_Encoder& DER_Encoder::raw_bytes(const uint8_t bytes[], size_t length) { + if (m_subsequences.size()) { + m_subsequences[m_subsequences.size() - 1].add_bytes(bytes, length); + } else if (m_append_output) { + m_append_output(bytes, length); + } else { + m_default_outbuf += std::make_pair(bytes, length); + } + + return (*this); +} + +/* + * Write the encoding of the byte(s) + */ +DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const uint8_t rep[], + size_t length) { + std::vector hdr; + encode_tag(hdr, type_tag, class_tag); + encode_length(hdr, length); + + if (m_subsequences.size()) { + m_subsequences[m_subsequences.size() - 1].add_bytes(hdr.data(), hdr.size(), rep, length); + } else if (m_append_output) { + m_append_output(hdr.data(), hdr.size()); + m_append_output(rep, length); + } else { + m_default_outbuf += hdr; + m_default_outbuf += std::make_pair(rep, length); + } + + return (*this); +} + +/* + * Encode a NULL object + */ +DER_Encoder& DER_Encoder::encode_null() { return add_object(NULL_TAG, UNIVERSAL, nullptr, 0); } + +/* + * DER encode a BOOLEAN + */ +DER_Encoder& DER_Encoder::encode(bool is_true) { return encode(is_true, BOOLEAN, UNIVERSAL); } + +/* + * DER encode a small INTEGER + */ +DER_Encoder& DER_Encoder::encode(size_t n) { return encode(BigInt(n), INTEGER, UNIVERSAL); } + +/* + * DER encode a small INTEGER + */ +DER_Encoder& DER_Encoder::encode(const BigInt& n) { return encode(n, INTEGER, UNIVERSAL); } + +/* + * Encode this object + */ +DER_Encoder& DER_Encoder::encode(const uint8_t bytes[], size_t length, ASN1_Tag real_type) { + return encode(bytes, length, real_type, real_type, UNIVERSAL); +} + +/* + * DER encode a BOOLEAN + */ +DER_Encoder& DER_Encoder::encode(bool is_true, ASN1_Tag type_tag, ASN1_Tag class_tag) { + uint8_t val = is_true ? 0xFF : 0x00; + return add_object(type_tag, class_tag, &val, 1); +} + +/* + * DER encode a small INTEGER + */ +DER_Encoder& DER_Encoder::encode(size_t n, ASN1_Tag type_tag, ASN1_Tag class_tag) { + return encode(BigInt(n), type_tag, class_tag); +} + +/* + * DER encode an INTEGER + */ +DER_Encoder& DER_Encoder::encode(const BigInt& n, ASN1_Tag type_tag, ASN1_Tag class_tag) { + if (n == 0) return add_object(type_tag, class_tag, 0); + + const size_t extra_zero = (n.bits() % 8 == 0) ? 1 : 0; + secure_vector contents(extra_zero + n.bytes()); + n.binary_encode(&contents[extra_zero]); + if (n < 0) { + for (size_t i = 0; i != contents.size(); ++i) contents[i] = ~contents[i]; + for (size_t i = contents.size(); i > 0; --i) + if (++contents[i - 1]) break; + } + + return add_object(type_tag, class_tag, contents); +} + +/* + * DER encode an OCTET STRING or BIT STRING + */ +DER_Encoder& DER_Encoder::encode(const uint8_t bytes[], size_t length, ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) { + if (real_type != OCTET_STRING && real_type != BIT_STRING) + throw Invalid_Argument("DER_Encoder: Invalid tag for byte/bit string"); + + if (real_type == BIT_STRING) { + secure_vector encoded; + encoded.push_back(0); + encoded += std::make_pair(bytes, length); + return add_object(type_tag, class_tag, encoded); + } else + return add_object(type_tag, class_tag, bytes, length); +} + +DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj) { + obj.encode_into(*this); + return (*this); +} + +/* + * Write the encoding of the byte(s) + */ +DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::string& rep_str) { + const uint8_t* rep = cast_char_ptr_to_uint8(rep_str.data()); + const size_t rep_len = rep_str.size(); + return add_object(type_tag, class_tag, rep, rep_len); +} + +/* + * Write the encoding of the byte + */ +DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, uint8_t rep) { + return add_object(type_tag, class_tag, &rep, 1); +} + +} // namespace Botan +/* + * OID maps + * + * This file was automatically generated by ./src/scripts/oids.py on 2019-08-03 + * + * All manual edits to this file will be lost. Edit the script + * then regenerate this source file. + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +std::unordered_map OIDS::load_oid2str_map() { + return std::unordered_map{ + {"0.3.4401.5.3.1.9.26", "Camellia-192/GCM"}, + {"0.3.4401.5.3.1.9.46", "Camellia-256/GCM"}, + {"0.3.4401.5.3.1.9.6", "Camellia-128/GCM"}, + {"1.0.14888.3.0.5", "ECKCDSA"}, + {"1.2.156.10197.1.104.100", "SM4/OCB"}, + {"1.2.156.10197.1.104.2", "SM4/CBC"}, + {"1.2.156.10197.1.104.8", "SM4/GCM"}, + {"1.2.156.10197.1.301", "sm2p256v1"}, + {"1.2.156.10197.1.301.1", "SM2"}, + {"1.2.156.10197.1.301.2", "SM2_Kex"}, + {"1.2.156.10197.1.301.3", "SM2_Enc"}, + {"1.2.156.10197.1.401", "SM3"}, + {"1.2.156.10197.1.501", "SM2_Sig/SM3"}, + {"1.2.156.10197.1.504", "RSA/EMSA3(SM3)"}, + {"1.2.250.1.223.101.256.1", "frp256v1"}, + {"1.2.392.200011.61.1.1.1.2", "Camellia-128/CBC"}, + {"1.2.392.200011.61.1.1.1.3", "Camellia-192/CBC"}, + {"1.2.392.200011.61.1.1.1.4", "Camellia-256/CBC"}, + {"1.2.410.200004.1.100.4.3", "ECKCDSA/EMSA1(SHA-1)"}, + {"1.2.410.200004.1.100.4.4", "ECKCDSA/EMSA1(SHA-224)"}, + {"1.2.410.200004.1.100.4.5", "ECKCDSA/EMSA1(SHA-256)"}, + {"1.2.410.200004.1.4", "SEED/CBC"}, + {"1.2.643.100.1", "GOST.OGRN"}, + {"1.2.643.100.111", "GOST.SubjectSigningTool"}, + {"1.2.643.100.112", "GOST.IssuerSigningTool"}, + {"1.2.643.2.2.19", "GOST-34.10"}, + {"1.2.643.2.2.3", "GOST-34.10/EMSA1(GOST-R-34.11-94)"}, + {"1.2.643.2.2.35.1", "gost_256A"}, + {"1.2.643.2.2.36.0", "gost_256A"}, + {"1.2.643.3.131.1.1", "GOST.INN"}, + {"1.2.643.7.1.1.1.1", "GOST-34.10-2012-256"}, + {"1.2.643.7.1.1.1.2", "GOST-34.10-2012-512"}, + {"1.2.643.7.1.1.2.2", "Streebog-256"}, + {"1.2.643.7.1.1.2.3", "Streebog-512"}, + {"1.2.643.7.1.1.3.2", "GOST-34.10-2012-256/EMSA1(Streebog-256)"}, + {"1.2.643.7.1.1.3.3", "GOST-34.10-2012-512/EMSA1(Streebog-512)"}, + {"1.2.643.7.1.2.1.1.1", "gost_256A"}, + {"1.2.643.7.1.2.1.1.2", "gost_256B"}, + {"1.2.643.7.1.2.1.2.1", "gost_512A"}, + {"1.2.643.7.1.2.1.2.2", "gost_512B"}, + {"1.2.840.10040.4.1", "DSA"}, + {"1.2.840.10040.4.3", "DSA/EMSA1(SHA-160)"}, + {"1.2.840.10045.2.1", "ECDSA"}, + {"1.2.840.10045.3.1.1", "secp192r1"}, + {"1.2.840.10045.3.1.2", "x962_p192v2"}, + {"1.2.840.10045.3.1.3", "x962_p192v3"}, + {"1.2.840.10045.3.1.4", "x962_p239v1"}, + {"1.2.840.10045.3.1.5", "x962_p239v2"}, + {"1.2.840.10045.3.1.6", "x962_p239v3"}, + {"1.2.840.10045.3.1.7", "secp256r1"}, + {"1.2.840.10045.4.1", "ECDSA/EMSA1(SHA-160)"}, + {"1.2.840.10045.4.3.1", "ECDSA/EMSA1(SHA-224)"}, + {"1.2.840.10045.4.3.2", "ECDSA/EMSA1(SHA-256)"}, + {"1.2.840.10045.4.3.3", "ECDSA/EMSA1(SHA-384)"}, + {"1.2.840.10045.4.3.4", "ECDSA/EMSA1(SHA-512)"}, + {"1.2.840.10046.2.1", "DH"}, + {"1.2.840.113533.7.66.10", "CAST-128/CBC"}, + {"1.2.840.113533.7.66.15", "KeyWrap.CAST-128"}, + {"1.2.840.113549.1.1.1", "RSA"}, + {"1.2.840.113549.1.1.10", "RSA/EMSA4"}, + {"1.2.840.113549.1.1.11", "RSA/EMSA3(SHA-256)"}, + {"1.2.840.113549.1.1.12", "RSA/EMSA3(SHA-384)"}, + {"1.2.840.113549.1.1.13", "RSA/EMSA3(SHA-512)"}, + {"1.2.840.113549.1.1.14", "RSA/EMSA3(SHA-224)"}, + {"1.2.840.113549.1.1.16", "RSA/EMSA3(SHA-512-256)"}, + {"1.2.840.113549.1.1.4", "RSA/EMSA3(MD5)"}, + {"1.2.840.113549.1.1.5", "RSA/EMSA3(SHA-160)"}, + {"1.2.840.113549.1.1.7", "RSA/OAEP"}, + {"1.2.840.113549.1.1.8", "MGF1"}, + {"1.2.840.113549.1.5.12", "PKCS5.PBKDF2"}, + {"1.2.840.113549.1.5.13", "PBE-PKCS5v20"}, + {"1.2.840.113549.1.9.1", "PKCS9.EmailAddress"}, + {"1.2.840.113549.1.9.14", "PKCS9.ExtensionRequest"}, + {"1.2.840.113549.1.9.16.3.18", "ChaCha20Poly1305"}, + {"1.2.840.113549.1.9.16.3.6", "KeyWrap.TripleDES"}, + {"1.2.840.113549.1.9.16.3.8", "Compression.Zlib"}, + {"1.2.840.113549.1.9.2", "PKCS9.UnstructuredName"}, + {"1.2.840.113549.1.9.3", "PKCS9.ContentType"}, + {"1.2.840.113549.1.9.4", "PKCS9.MessageDigest"}, + {"1.2.840.113549.1.9.7", "PKCS9.ChallengePassword"}, + {"1.2.840.113549.2.10", "HMAC(SHA-384)"}, + {"1.2.840.113549.2.11", "HMAC(SHA-512)"}, + {"1.2.840.113549.2.13", "HMAC(SHA-512-256)"}, + {"1.2.840.113549.2.5", "MD5"}, + {"1.2.840.113549.2.7", "HMAC(SHA-160)"}, + {"1.2.840.113549.2.8", "HMAC(SHA-224)"}, + {"1.2.840.113549.2.9", "HMAC(SHA-256)"}, + {"1.2.840.113549.3.7", "TripleDES/CBC"}, + {"1.3.101.110", "Curve25519"}, + {"1.3.101.112", "Ed25519"}, + {"1.3.132.0.10", "secp256k1"}, + {"1.3.132.0.30", "secp160r2"}, + {"1.3.132.0.31", "secp192k1"}, + {"1.3.132.0.32", "secp224k1"}, + {"1.3.132.0.33", "secp224r1"}, + {"1.3.132.0.34", "secp384r1"}, + {"1.3.132.0.35", "secp521r1"}, + {"1.3.132.0.8", "secp160r1"}, + {"1.3.132.0.9", "secp160k1"}, + {"1.3.132.1.12", "ECDH"}, + {"1.3.14.3.2.26", "SHA-160"}, + {"1.3.14.3.2.7", "DES/CBC"}, + {"1.3.36.3.2.1", "RIPEMD-160"}, + {"1.3.36.3.3.1.2", "RSA/EMSA3(RIPEMD-160)"}, + {"1.3.36.3.3.2.5.2.1", "ECGDSA"}, + {"1.3.36.3.3.2.5.4.1", "ECGDSA/EMSA1(RIPEMD-160)"}, + {"1.3.36.3.3.2.5.4.2", "ECGDSA/EMSA1(SHA-160)"}, + {"1.3.36.3.3.2.5.4.3", "ECGDSA/EMSA1(SHA-224)"}, + {"1.3.36.3.3.2.5.4.4", "ECGDSA/EMSA1(SHA-256)"}, + {"1.3.36.3.3.2.5.4.5", "ECGDSA/EMSA1(SHA-384)"}, + {"1.3.36.3.3.2.5.4.6", "ECGDSA/EMSA1(SHA-512)"}, + {"1.3.36.3.3.2.8.1.1.1", "brainpool160r1"}, + {"1.3.36.3.3.2.8.1.1.11", "brainpool384r1"}, + {"1.3.36.3.3.2.8.1.1.13", "brainpool512r1"}, + {"1.3.36.3.3.2.8.1.1.3", "brainpool192r1"}, + {"1.3.36.3.3.2.8.1.1.5", "brainpool224r1"}, + {"1.3.36.3.3.2.8.1.1.7", "brainpool256r1"}, + {"1.3.36.3.3.2.8.1.1.9", "brainpool320r1"}, + {"1.3.6.1.4.1.11591.12.2", "Tiger(24,3)"}, + {"1.3.6.1.4.1.11591.15.1", "OpenPGP.Ed25519"}, + {"1.3.6.1.4.1.11591.4.11", "Scrypt"}, + {"1.3.6.1.4.1.25258.1.3", "McEliece"}, + {"1.3.6.1.4.1.25258.1.5", "XMSS-draft6"}, + {"1.3.6.1.4.1.25258.1.6.1", "GOST-34.10-2012-256/EMSA1(SHA-256)"}, + {"1.3.6.1.4.1.25258.1.8", "XMSS"}, + {"1.3.6.1.4.1.25258.3.1", "Serpent/CBC"}, + {"1.3.6.1.4.1.25258.3.101", "Serpent/GCM"}, + {"1.3.6.1.4.1.25258.3.102", "Twofish/GCM"}, + {"1.3.6.1.4.1.25258.3.2", "Threefish-512/CBC"}, + {"1.3.6.1.4.1.25258.3.2.1", "AES-128/OCB"}, + {"1.3.6.1.4.1.25258.3.2.2", "AES-192/OCB"}, + {"1.3.6.1.4.1.25258.3.2.3", "AES-256/OCB"}, + {"1.3.6.1.4.1.25258.3.2.4", "Serpent/OCB"}, + {"1.3.6.1.4.1.25258.3.2.5", "Twofish/OCB"}, + {"1.3.6.1.4.1.25258.3.2.6", "Camellia-128/OCB"}, + {"1.3.6.1.4.1.25258.3.2.7", "Camellia-192/OCB"}, + {"1.3.6.1.4.1.25258.3.2.8", "Camellia-256/OCB"}, + {"1.3.6.1.4.1.25258.3.3", "Twofish/CBC"}, + {"1.3.6.1.4.1.25258.3.4.1", "AES-128/SIV"}, + {"1.3.6.1.4.1.25258.3.4.2", "AES-192/SIV"}, + {"1.3.6.1.4.1.25258.3.4.3", "AES-256/SIV"}, + {"1.3.6.1.4.1.25258.3.4.4", "Serpent/SIV"}, + {"1.3.6.1.4.1.25258.3.4.5", "Twofish/SIV"}, + {"1.3.6.1.4.1.25258.3.4.6", "Camellia-128/SIV"}, + {"1.3.6.1.4.1.25258.3.4.7", "Camellia-192/SIV"}, + {"1.3.6.1.4.1.25258.3.4.8", "Camellia-256/SIV"}, + {"1.3.6.1.4.1.25258.3.4.9", "SM4/SIV"}, + {"1.3.6.1.4.1.3029.1.2.1", "ElGamal"}, + {"1.3.6.1.4.1.3029.1.5.1", "OpenPGP.Curve25519"}, + {"1.3.6.1.4.1.311.20.2.2", "Microsoft SmartcardLogon"}, + {"1.3.6.1.4.1.311.20.2.3", "Microsoft UPN"}, + {"1.3.6.1.4.1.8301.3.1.2.9.0.38", "secp521r1"}, + {"1.3.6.1.5.5.7.1.1", "PKIX.AuthorityInformationAccess"}, + {"1.3.6.1.5.5.7.3.1", "PKIX.ServerAuth"}, + {"1.3.6.1.5.5.7.3.2", "PKIX.ClientAuth"}, + {"1.3.6.1.5.5.7.3.3", "PKIX.CodeSigning"}, + {"1.3.6.1.5.5.7.3.4", "PKIX.EmailProtection"}, + {"1.3.6.1.5.5.7.3.5", "PKIX.IPsecEndSystem"}, + {"1.3.6.1.5.5.7.3.6", "PKIX.IPsecTunnel"}, + {"1.3.6.1.5.5.7.3.7", "PKIX.IPsecUser"}, + {"1.3.6.1.5.5.7.3.8", "PKIX.TimeStamping"}, + {"1.3.6.1.5.5.7.3.9", "PKIX.OCSPSigning"}, + {"1.3.6.1.5.5.7.48.1", "PKIX.OCSP"}, + {"1.3.6.1.5.5.7.48.1.1", "PKIX.OCSP.BasicResponse"}, + {"1.3.6.1.5.5.7.48.2", "PKIX.CertificateAuthorityIssuers"}, + {"1.3.6.1.5.5.7.8.5", "PKIX.XMPPAddr"}, + {"2.16.840.1.101.3.4.1.2", "AES-128/CBC"}, + {"2.16.840.1.101.3.4.1.22", "AES-192/CBC"}, + {"2.16.840.1.101.3.4.1.25", "KeyWrap.AES-192"}, + {"2.16.840.1.101.3.4.1.26", "AES-192/GCM"}, + {"2.16.840.1.101.3.4.1.27", "AES-192/CCM"}, + {"2.16.840.1.101.3.4.1.42", "AES-256/CBC"}, + {"2.16.840.1.101.3.4.1.45", "KeyWrap.AES-256"}, + {"2.16.840.1.101.3.4.1.46", "AES-256/GCM"}, + {"2.16.840.1.101.3.4.1.47", "AES-256/CCM"}, + {"2.16.840.1.101.3.4.1.5", "KeyWrap.AES-128"}, + {"2.16.840.1.101.3.4.1.6", "AES-128/GCM"}, + {"2.16.840.1.101.3.4.1.7", "AES-128/CCM"}, + {"2.16.840.1.101.3.4.2.1", "SHA-256"}, + {"2.16.840.1.101.3.4.2.10", "SHA-3(512)"}, + {"2.16.840.1.101.3.4.2.11", "SHAKE-128"}, + {"2.16.840.1.101.3.4.2.12", "SHAKE-256"}, + {"2.16.840.1.101.3.4.2.2", "SHA-384"}, + {"2.16.840.1.101.3.4.2.3", "SHA-512"}, + {"2.16.840.1.101.3.4.2.4", "SHA-224"}, + {"2.16.840.1.101.3.4.2.6", "SHA-512-256"}, + {"2.16.840.1.101.3.4.2.7", "SHA-3(224)"}, + {"2.16.840.1.101.3.4.2.8", "SHA-3(256)"}, + {"2.16.840.1.101.3.4.2.9", "SHA-3(384)"}, + {"2.16.840.1.101.3.4.3.1", "DSA/EMSA1(SHA-224)"}, + {"2.16.840.1.101.3.4.3.10", "ECDSA/EMSA1(SHA-3(256))"}, + {"2.16.840.1.101.3.4.3.11", "ECDSA/EMSA1(SHA-3(384))"}, + {"2.16.840.1.101.3.4.3.12", "ECDSA/EMSA1(SHA-3(512))"}, + {"2.16.840.1.101.3.4.3.13", "RSA/EMSA3(SHA-3(224))"}, + {"2.16.840.1.101.3.4.3.14", "RSA/EMSA3(SHA-3(256))"}, + {"2.16.840.1.101.3.4.3.15", "RSA/EMSA3(SHA-3(384))"}, + {"2.16.840.1.101.3.4.3.16", "RSA/EMSA3(SHA-3(512))"}, + {"2.16.840.1.101.3.4.3.2", "DSA/EMSA1(SHA-256)"}, + {"2.16.840.1.101.3.4.3.3", "DSA/EMSA1(SHA-384)"}, + {"2.16.840.1.101.3.4.3.4", "DSA/EMSA1(SHA-512)"}, + {"2.16.840.1.101.3.4.3.5", "DSA/EMSA1(SHA-3(224))"}, + {"2.16.840.1.101.3.4.3.6", "DSA/EMSA1(SHA-3(256))"}, + {"2.16.840.1.101.3.4.3.7", "DSA/EMSA1(SHA-3(384))"}, + {"2.16.840.1.101.3.4.3.8", "DSA/EMSA1(SHA-3(512))"}, + {"2.16.840.1.101.3.4.3.9", "ECDSA/EMSA1(SHA-3(224))"}, + {"2.16.840.1.113730.1.13", "Certificate Comment"}, + {"2.5.29.14", "X509v3.SubjectKeyIdentifier"}, + {"2.5.29.15", "X509v3.KeyUsage"}, + {"2.5.29.16", "X509v3.PrivateKeyUsagePeriod"}, + {"2.5.29.17", "X509v3.SubjectAlternativeName"}, + {"2.5.29.18", "X509v3.IssuerAlternativeName"}, + {"2.5.29.19", "X509v3.BasicConstraints"}, + {"2.5.29.20", "X509v3.CRLNumber"}, + {"2.5.29.21", "X509v3.ReasonCode"}, + {"2.5.29.23", "X509v3.HoldInstructionCode"}, + {"2.5.29.24", "X509v3.InvalidityDate"}, + {"2.5.29.28", "X509v3.CRLIssuingDistributionPoint"}, + {"2.5.29.30", "X509v3.NameConstraints"}, + {"2.5.29.31", "X509v3.CRLDistributionPoints"}, + {"2.5.29.32", "X509v3.CertificatePolicies"}, + {"2.5.29.32.0", "X509v3.AnyPolicy"}, + {"2.5.29.35", "X509v3.AuthorityKeyIdentifier"}, + {"2.5.29.36", "X509v3.PolicyConstraints"}, + {"2.5.29.37", "X509v3.ExtendedKeyUsage"}, + {"2.5.4.10", "X520.Organization"}, + {"2.5.4.11", "X520.OrganizationalUnit"}, + {"2.5.4.12", "X520.Title"}, + {"2.5.4.3", "X520.CommonName"}, + {"2.5.4.4", "X520.Surname"}, + {"2.5.4.42", "X520.GivenName"}, + {"2.5.4.43", "X520.Initials"}, + {"2.5.4.44", "X520.GenerationalQualifier"}, + {"2.5.4.46", "X520.DNQualifier"}, + {"2.5.4.5", "X520.SerialNumber"}, + {"2.5.4.6", "X520.Country"}, + {"2.5.4.65", "X520.Pseudonym"}, + {"2.5.4.7", "X520.Locality"}, + {"2.5.4.8", "X520.State"}, + {"2.5.4.9", "X520.StreetAddress"}, + {"2.5.8.1.1", "RSA"}}; +} + +std::unordered_map OIDS::load_str2oid_map() { + return std::unordered_map{ + {"AES-128/CBC", OID({2, 16, 840, 1, 101, 3, 4, 1, 2})}, + {"AES-128/CCM", OID({2, 16, 840, 1, 101, 3, 4, 1, 7})}, + {"AES-128/GCM", OID({2, 16, 840, 1, 101, 3, 4, 1, 6})}, + {"AES-128/OCB", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2, 1})}, + {"AES-128/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 1})}, + {"AES-192/CBC", OID({2, 16, 840, 1, 101, 3, 4, 1, 22})}, + {"AES-192/CCM", OID({2, 16, 840, 1, 101, 3, 4, 1, 27})}, + {"AES-192/GCM", OID({2, 16, 840, 1, 101, 3, 4, 1, 26})}, + {"AES-192/OCB", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2, 2})}, + {"AES-192/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 2})}, + {"AES-256/CBC", OID({2, 16, 840, 1, 101, 3, 4, 1, 42})}, + {"AES-256/CCM", OID({2, 16, 840, 1, 101, 3, 4, 1, 47})}, + {"AES-256/GCM", OID({2, 16, 840, 1, 101, 3, 4, 1, 46})}, + {"AES-256/OCB", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2, 3})}, + {"AES-256/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 3})}, + {"CAST-128/CBC", OID({1, 2, 840, 113533, 7, 66, 10})}, + {"Camellia-128/CBC", OID({1, 2, 392, 200011, 61, 1, 1, 1, 2})}, + {"Camellia-128/GCM", OID({0, 3, 4401, 5, 3, 1, 9, 6})}, + {"Camellia-128/OCB", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2, 6})}, + {"Camellia-128/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 6})}, + {"Camellia-192/CBC", OID({1, 2, 392, 200011, 61, 1, 1, 1, 3})}, + {"Camellia-192/GCM", OID({0, 3, 4401, 5, 3, 1, 9, 26})}, + {"Camellia-192/OCB", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2, 7})}, + {"Camellia-192/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 7})}, + {"Camellia-256/CBC", OID({1, 2, 392, 200011, 61, 1, 1, 1, 4})}, + {"Camellia-256/GCM", OID({0, 3, 4401, 5, 3, 1, 9, 46})}, + {"Camellia-256/OCB", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2, 8})}, + {"Camellia-256/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 8})}, + {"Certificate Comment", OID({2, 16, 840, 1, 113730, 1, 13})}, + {"ChaCha20Poly1305", OID({1, 2, 840, 113549, 1, 9, 16, 3, 18})}, + {"Compression.Zlib", OID({1, 2, 840, 113549, 1, 9, 16, 3, 8})}, + {"Curve25519", OID({1, 3, 101, 110})}, + {"DES/CBC", OID({1, 3, 14, 3, 2, 7})}, + {"DH", OID({1, 2, 840, 10046, 2, 1})}, + {"DSA", OID({1, 2, 840, 10040, 4, 1})}, + {"DSA/EMSA1(SHA-160)", OID({1, 2, 840, 10040, 4, 3})}, + {"DSA/EMSA1(SHA-224)", OID({2, 16, 840, 1, 101, 3, 4, 3, 1})}, + {"DSA/EMSA1(SHA-256)", OID({2, 16, 840, 1, 101, 3, 4, 3, 2})}, + {"DSA/EMSA1(SHA-3(224))", OID({2, 16, 840, 1, 101, 3, 4, 3, 5})}, + {"DSA/EMSA1(SHA-3(256))", OID({2, 16, 840, 1, 101, 3, 4, 3, 6})}, + {"DSA/EMSA1(SHA-3(384))", OID({2, 16, 840, 1, 101, 3, 4, 3, 7})}, + {"DSA/EMSA1(SHA-3(512))", OID({2, 16, 840, 1, 101, 3, 4, 3, 8})}, + {"DSA/EMSA1(SHA-384)", OID({2, 16, 840, 1, 101, 3, 4, 3, 3})}, + {"DSA/EMSA1(SHA-512)", OID({2, 16, 840, 1, 101, 3, 4, 3, 4})}, + {"ECDH", OID({1, 3, 132, 1, 12})}, + {"ECDSA", OID({1, 2, 840, 10045, 2, 1})}, + {"ECDSA/EMSA1(SHA-160)", OID({1, 2, 840, 10045, 4, 1})}, + {"ECDSA/EMSA1(SHA-224)", OID({1, 2, 840, 10045, 4, 3, 1})}, + {"ECDSA/EMSA1(SHA-256)", OID({1, 2, 840, 10045, 4, 3, 2})}, + {"ECDSA/EMSA1(SHA-3(224))", OID({2, 16, 840, 1, 101, 3, 4, 3, 9})}, + {"ECDSA/EMSA1(SHA-3(256))", OID({2, 16, 840, 1, 101, 3, 4, 3, 10})}, + {"ECDSA/EMSA1(SHA-3(384))", OID({2, 16, 840, 1, 101, 3, 4, 3, 11})}, + {"ECDSA/EMSA1(SHA-3(512))", OID({2, 16, 840, 1, 101, 3, 4, 3, 12})}, + {"ECDSA/EMSA1(SHA-384)", OID({1, 2, 840, 10045, 4, 3, 3})}, + {"ECDSA/EMSA1(SHA-512)", OID({1, 2, 840, 10045, 4, 3, 4})}, + {"ECGDSA", OID({1, 3, 36, 3, 3, 2, 5, 2, 1})}, + {"ECGDSA/EMSA1(RIPEMD-160)", OID({1, 3, 36, 3, 3, 2, 5, 4, 1})}, + {"ECGDSA/EMSA1(SHA-160)", OID({1, 3, 36, 3, 3, 2, 5, 4, 2})}, + {"ECGDSA/EMSA1(SHA-224)", OID({1, 3, 36, 3, 3, 2, 5, 4, 3})}, + {"ECGDSA/EMSA1(SHA-256)", OID({1, 3, 36, 3, 3, 2, 5, 4, 4})}, + {"ECGDSA/EMSA1(SHA-384)", OID({1, 3, 36, 3, 3, 2, 5, 4, 5})}, + {"ECGDSA/EMSA1(SHA-512)", OID({1, 3, 36, 3, 3, 2, 5, 4, 6})}, + {"ECKCDSA", OID({1, 0, 14888, 3, 0, 5})}, + {"ECKCDSA/EMSA1(SHA-1)", OID({1, 2, 410, 200004, 1, 100, 4, 3})}, + {"ECKCDSA/EMSA1(SHA-224)", OID({1, 2, 410, 200004, 1, 100, 4, 4})}, + {"ECKCDSA/EMSA1(SHA-256)", OID({1, 2, 410, 200004, 1, 100, 4, 5})}, + {"Ed25519", OID({1, 3, 101, 112})}, + {"ElGamal", OID({1, 3, 6, 1, 4, 1, 3029, 1, 2, 1})}, + {"GOST-34.10", OID({1, 2, 643, 2, 2, 19})}, + {"GOST-34.10-2012-256", OID({1, 2, 643, 7, 1, 1, 1, 1})}, + {"GOST-34.10-2012-256/EMSA1(SHA-256)", OID({1, 3, 6, 1, 4, 1, 25258, 1, 6, 1})}, + {"GOST-34.10-2012-256/EMSA1(Streebog-256)", OID({1, 2, 643, 7, 1, 1, 3, 2})}, + {"GOST-34.10-2012-512", OID({1, 2, 643, 7, 1, 1, 1, 2})}, + {"GOST-34.10-2012-512/EMSA1(Streebog-512)", OID({1, 2, 643, 7, 1, 1, 3, 3})}, + {"GOST-34.10/EMSA1(GOST-R-34.11-94)", OID({1, 2, 643, 2, 2, 3})}, + {"GOST.INN", OID({1, 2, 643, 3, 131, 1, 1})}, + {"GOST.IssuerSigningTool", OID({1, 2, 643, 100, 112})}, + {"GOST.OGRN", OID({1, 2, 643, 100, 1})}, + {"GOST.SubjectSigningTool", OID({1, 2, 643, 100, 111})}, + {"HMAC(SHA-160)", OID({1, 2, 840, 113549, 2, 7})}, + {"HMAC(SHA-224)", OID({1, 2, 840, 113549, 2, 8})}, + {"HMAC(SHA-256)", OID({1, 2, 840, 113549, 2, 9})}, + {"HMAC(SHA-384)", OID({1, 2, 840, 113549, 2, 10})}, + {"HMAC(SHA-512)", OID({1, 2, 840, 113549, 2, 11})}, + {"HMAC(SHA-512-256)", OID({1, 2, 840, 113549, 2, 13})}, + {"KeyWrap.AES-128", OID({2, 16, 840, 1, 101, 3, 4, 1, 5})}, + {"KeyWrap.AES-192", OID({2, 16, 840, 1, 101, 3, 4, 1, 25})}, + {"KeyWrap.AES-256", OID({2, 16, 840, 1, 101, 3, 4, 1, 45})}, + {"KeyWrap.CAST-128", OID({1, 2, 840, 113533, 7, 66, 15})}, + {"KeyWrap.TripleDES", OID({1, 2, 840, 113549, 1, 9, 16, 3, 6})}, + {"MD5", OID({1, 2, 840, 113549, 2, 5})}, + {"MGF1", OID({1, 2, 840, 113549, 1, 1, 8})}, + {"McEliece", OID({1, 3, 6, 1, 4, 1, 25258, 1, 3})}, + {"Microsoft SmartcardLogon", OID({1, 3, 6, 1, 4, 1, 311, 20, 2, 2})}, + {"Microsoft UPN", OID({1, 3, 6, 1, 4, 1, 311, 20, 2, 3})}, + {"OpenPGP.Curve25519", OID({1, 3, 6, 1, 4, 1, 3029, 1, 5, 1})}, + {"OpenPGP.Ed25519", OID({1, 3, 6, 1, 4, 1, 11591, 15, 1})}, + {"PBE-PKCS5v20", OID({1, 2, 840, 113549, 1, 5, 13})}, + {"PBES2", OID({1, 2, 840, 113549, 1, 5, 13})}, + {"PKCS5.PBKDF2", OID({1, 2, 840, 113549, 1, 5, 12})}, + {"PKCS9.ChallengePassword", OID({1, 2, 840, 113549, 1, 9, 7})}, + {"PKCS9.ContentType", OID({1, 2, 840, 113549, 1, 9, 3})}, + {"PKCS9.EmailAddress", OID({1, 2, 840, 113549, 1, 9, 1})}, + {"PKCS9.ExtensionRequest", OID({1, 2, 840, 113549, 1, 9, 14})}, + {"PKCS9.MessageDigest", OID({1, 2, 840, 113549, 1, 9, 4})}, + {"PKCS9.UnstructuredName", OID({1, 2, 840, 113549, 1, 9, 2})}, + {"PKIX.AuthorityInformationAccess", OID({1, 3, 6, 1, 5, 5, 7, 1, 1})}, + {"PKIX.CertificateAuthorityIssuers", OID({1, 3, 6, 1, 5, 5, 7, 48, 2})}, + {"PKIX.ClientAuth", OID({1, 3, 6, 1, 5, 5, 7, 3, 2})}, + {"PKIX.CodeSigning", OID({1, 3, 6, 1, 5, 5, 7, 3, 3})}, + {"PKIX.EmailProtection", OID({1, 3, 6, 1, 5, 5, 7, 3, 4})}, + {"PKIX.IPsecEndSystem", OID({1, 3, 6, 1, 5, 5, 7, 3, 5})}, + {"PKIX.IPsecTunnel", OID({1, 3, 6, 1, 5, 5, 7, 3, 6})}, + {"PKIX.IPsecUser", OID({1, 3, 6, 1, 5, 5, 7, 3, 7})}, + {"PKIX.OCSP", OID({1, 3, 6, 1, 5, 5, 7, 48, 1})}, + {"PKIX.OCSP.BasicResponse", OID({1, 3, 6, 1, 5, 5, 7, 48, 1, 1})}, + {"PKIX.OCSPSigning", OID({1, 3, 6, 1, 5, 5, 7, 3, 9})}, + {"PKIX.ServerAuth", OID({1, 3, 6, 1, 5, 5, 7, 3, 1})}, + {"PKIX.TimeStamping", OID({1, 3, 6, 1, 5, 5, 7, 3, 8})}, + {"PKIX.XMPPAddr", OID({1, 3, 6, 1, 5, 5, 7, 8, 5})}, + {"RIPEMD-160", OID({1, 3, 36, 3, 2, 1})}, + {"RSA", OID({1, 2, 840, 113549, 1, 1, 1})}, + {"RSA/EMSA3(MD5)", OID({1, 2, 840, 113549, 1, 1, 4})}, + {"RSA/EMSA3(RIPEMD-160)", OID({1, 3, 36, 3, 3, 1, 2})}, + {"RSA/EMSA3(SHA-160)", OID({1, 2, 840, 113549, 1, 1, 5})}, + {"RSA/EMSA3(SHA-224)", OID({1, 2, 840, 113549, 1, 1, 14})}, + {"RSA/EMSA3(SHA-256)", OID({1, 2, 840, 113549, 1, 1, 11})}, + {"RSA/EMSA3(SHA-3(224))", OID({2, 16, 840, 1, 101, 3, 4, 3, 13})}, + {"RSA/EMSA3(SHA-3(256))", OID({2, 16, 840, 1, 101, 3, 4, 3, 14})}, + {"RSA/EMSA3(SHA-3(384))", OID({2, 16, 840, 1, 101, 3, 4, 3, 15})}, + {"RSA/EMSA3(SHA-3(512))", OID({2, 16, 840, 1, 101, 3, 4, 3, 16})}, + {"RSA/EMSA3(SHA-384)", OID({1, 2, 840, 113549, 1, 1, 12})}, + {"RSA/EMSA3(SHA-512)", OID({1, 2, 840, 113549, 1, 1, 13})}, + {"RSA/EMSA3(SHA-512-256)", OID({1, 2, 840, 113549, 1, 1, 16})}, + {"RSA/EMSA3(SM3)", OID({1, 2, 156, 10197, 1, 504})}, + {"RSA/EMSA4", OID({1, 2, 840, 113549, 1, 1, 10})}, + {"RSA/OAEP", OID({1, 2, 840, 113549, 1, 1, 7})}, + {"SEED/CBC", OID({1, 2, 410, 200004, 1, 4})}, + {"SHA-160", OID({1, 3, 14, 3, 2, 26})}, + {"SHA-224", OID({2, 16, 840, 1, 101, 3, 4, 2, 4})}, + {"SHA-256", OID({2, 16, 840, 1, 101, 3, 4, 2, 1})}, + {"SHA-3(224)", OID({2, 16, 840, 1, 101, 3, 4, 2, 7})}, + {"SHA-3(256)", OID({2, 16, 840, 1, 101, 3, 4, 2, 8})}, + {"SHA-3(384)", OID({2, 16, 840, 1, 101, 3, 4, 2, 9})}, + {"SHA-3(512)", OID({2, 16, 840, 1, 101, 3, 4, 2, 10})}, + {"SHA-384", OID({2, 16, 840, 1, 101, 3, 4, 2, 2})}, + {"SHA-512", OID({2, 16, 840, 1, 101, 3, 4, 2, 3})}, + {"SHA-512-256", OID({2, 16, 840, 1, 101, 3, 4, 2, 6})}, + {"SHAKE-128", OID({2, 16, 840, 1, 101, 3, 4, 2, 11})}, + {"SHAKE-256", OID({2, 16, 840, 1, 101, 3, 4, 2, 12})}, + {"SM2", OID({1, 2, 156, 10197, 1, 301, 1})}, + {"SM2_Enc", OID({1, 2, 156, 10197, 1, 301, 3})}, + {"SM2_Kex", OID({1, 2, 156, 10197, 1, 301, 2})}, + {"SM2_Sig", OID({1, 2, 156, 10197, 1, 301, 1})}, + {"SM2_Sig/SM3", OID({1, 2, 156, 10197, 1, 501})}, + {"SM3", OID({1, 2, 156, 10197, 1, 401})}, + {"SM4/CBC", OID({1, 2, 156, 10197, 1, 104, 2})}, + {"SM4/GCM", OID({1, 2, 156, 10197, 1, 104, 8})}, + {"SM4/OCB", OID({1, 2, 156, 10197, 1, 104, 100})}, + {"SM4/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 9})}, + {"Scrypt", OID({1, 3, 6, 1, 4, 1, 11591, 4, 11})}, + {"Serpent/CBC", OID({1, 3, 6, 1, 4, 1, 25258, 3, 1})}, + {"Serpent/GCM", OID({1, 3, 6, 1, 4, 1, 25258, 3, 101})}, + {"Serpent/OCB", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2, 4})}, + {"Serpent/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 4})}, + {"Streebog-256", OID({1, 2, 643, 7, 1, 1, 2, 2})}, + {"Streebog-512", OID({1, 2, 643, 7, 1, 1, 2, 3})}, + {"Threefish-512/CBC", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2})}, + {"Tiger(24,3)", OID({1, 3, 6, 1, 4, 1, 11591, 12, 2})}, + {"TripleDES/CBC", OID({1, 2, 840, 113549, 3, 7})}, + {"Twofish/CBC", OID({1, 3, 6, 1, 4, 1, 25258, 3, 3})}, + {"Twofish/GCM", OID({1, 3, 6, 1, 4, 1, 25258, 3, 102})}, + {"Twofish/OCB", OID({1, 3, 6, 1, 4, 1, 25258, 3, 2, 5})}, + {"Twofish/SIV", OID({1, 3, 6, 1, 4, 1, 25258, 3, 4, 5})}, + {"X509v3.AnyPolicy", OID({2, 5, 29, 32, 0})}, + {"X509v3.AuthorityKeyIdentifier", OID({2, 5, 29, 35})}, + {"X509v3.BasicConstraints", OID({2, 5, 29, 19})}, + {"X509v3.CRLDistributionPoints", OID({2, 5, 29, 31})}, + {"X509v3.CRLIssuingDistributionPoint", OID({2, 5, 29, 28})}, + {"X509v3.CRLNumber", OID({2, 5, 29, 20})}, + {"X509v3.CertificatePolicies", OID({2, 5, 29, 32})}, + {"X509v3.ExtendedKeyUsage", OID({2, 5, 29, 37})}, + {"X509v3.HoldInstructionCode", OID({2, 5, 29, 23})}, + {"X509v3.InvalidityDate", OID({2, 5, 29, 24})}, + {"X509v3.IssuerAlternativeName", OID({2, 5, 29, 18})}, + {"X509v3.KeyUsage", OID({2, 5, 29, 15})}, + {"X509v3.NameConstraints", OID({2, 5, 29, 30})}, + {"X509v3.PolicyConstraints", OID({2, 5, 29, 36})}, + {"X509v3.PrivateKeyUsagePeriod", OID({2, 5, 29, 16})}, + {"X509v3.ReasonCode", OID({2, 5, 29, 21})}, + {"X509v3.SubjectAlternativeName", OID({2, 5, 29, 17})}, + {"X509v3.SubjectKeyIdentifier", OID({2, 5, 29, 14})}, + {"X520.CommonName", OID({2, 5, 4, 3})}, + {"X520.Country", OID({2, 5, 4, 6})}, + {"X520.DNQualifier", OID({2, 5, 4, 46})}, + {"X520.GenerationalQualifier", OID({2, 5, 4, 44})}, + {"X520.GivenName", OID({2, 5, 4, 42})}, + {"X520.Initials", OID({2, 5, 4, 43})}, + {"X520.Locality", OID({2, 5, 4, 7})}, + {"X520.Organization", OID({2, 5, 4, 10})}, + {"X520.OrganizationalUnit", OID({2, 5, 4, 11})}, + {"X520.Pseudonym", OID({2, 5, 4, 65})}, + {"X520.SerialNumber", OID({2, 5, 4, 5})}, + {"X520.State", OID({2, 5, 4, 8})}, + {"X520.StreetAddress", OID({2, 5, 4, 9})}, + {"X520.Surname", OID({2, 5, 4, 4})}, + {"X520.Title", OID({2, 5, 4, 12})}, + {"XMSS", OID({1, 3, 6, 1, 4, 1, 25258, 1, 8})}, + {"XMSS-draft6", OID({1, 3, 6, 1, 4, 1, 25258, 1, 5})}, + {"brainpool160r1", OID({1, 3, 36, 3, 3, 2, 8, 1, 1, 1})}, + {"brainpool192r1", OID({1, 3, 36, 3, 3, 2, 8, 1, 1, 3})}, + {"brainpool224r1", OID({1, 3, 36, 3, 3, 2, 8, 1, 1, 5})}, + {"brainpool256r1", OID({1, 3, 36, 3, 3, 2, 8, 1, 1, 7})}, + {"brainpool320r1", OID({1, 3, 36, 3, 3, 2, 8, 1, 1, 9})}, + {"brainpool384r1", OID({1, 3, 36, 3, 3, 2, 8, 1, 1, 11})}, + {"brainpool512r1", OID({1, 3, 36, 3, 3, 2, 8, 1, 1, 13})}, + {"frp256v1", OID({1, 2, 250, 1, 223, 101, 256, 1})}, + {"gost_256A", OID({1, 2, 643, 7, 1, 2, 1, 1, 1})}, + {"gost_256B", OID({1, 2, 643, 7, 1, 2, 1, 1, 2})}, + {"gost_512A", OID({1, 2, 643, 7, 1, 2, 1, 2, 1})}, + {"gost_512B", OID({1, 2, 643, 7, 1, 2, 1, 2, 2})}, + {"secp160k1", OID({1, 3, 132, 0, 9})}, + {"secp160r1", OID({1, 3, 132, 0, 8})}, + {"secp160r2", OID({1, 3, 132, 0, 30})}, + {"secp192k1", OID({1, 3, 132, 0, 31})}, + {"secp192r1", OID({1, 2, 840, 10045, 3, 1, 1})}, + {"secp224k1", OID({1, 3, 132, 0, 32})}, + {"secp224r1", OID({1, 3, 132, 0, 33})}, + {"secp256k1", OID({1, 3, 132, 0, 10})}, + {"secp256r1", OID({1, 2, 840, 10045, 3, 1, 7})}, + {"secp384r1", OID({1, 3, 132, 0, 34})}, + {"secp521r1", OID({1, 3, 132, 0, 35})}, + {"sm2p256v1", OID({1, 2, 156, 10197, 1, 301})}, + {"x962_p192v2", OID({1, 2, 840, 10045, 3, 1, 2})}, + {"x962_p192v3", OID({1, 2, 840, 10045, 3, 1, 3})}, + {"x962_p239v1", OID({1, 2, 840, 10045, 3, 1, 4})}, + {"x962_p239v2", OID({1, 2, 840, 10045, 3, 1, 5})}, + {"x962_p239v3", OID({1, 2, 840, 10045, 3, 1, 6})}}; +} + +} // namespace Botan + +/* + * OID Registry + * (C) 1999-2008,2013 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +namespace { + +class OID_Map final { + public: + void add_oid(const OID& oid, const std::string& str) { + add_str2oid(oid, str); + add_oid2str(oid, str); + } + + void add_str2oid(const OID& oid, const std::string& str) { + lock_guard_type lock(m_mutex); + auto i = m_str2oid.find(str); + if (i == m_str2oid.end()) m_str2oid.insert(std::make_pair(str, oid)); + } + + void add_oid2str(const OID& oid, const std::string& str) { + const std::string oid_str = oid.to_string(); + lock_guard_type lock(m_mutex); + auto i = m_oid2str.find(oid_str); + if (i == m_oid2str.end()) m_oid2str.insert(std::make_pair(oid_str, str)); + } + + std::string oid2str(const OID& oid) { + const std::string oid_str = oid.to_string(); + + lock_guard_type lock(m_mutex); + + auto i = m_oid2str.find(oid_str); + if (i != m_oid2str.end()) return i->second; + + return ""; + } + + OID str2oid(const std::string& str) { + lock_guard_type lock(m_mutex); + auto i = m_str2oid.find(str); + if (i != m_str2oid.end()) return i->second; + + return OID(); + } + + bool have_oid(const std::string& str) { + lock_guard_type lock(m_mutex); + return m_str2oid.find(str) != m_str2oid.end(); + } + + static OID_Map& global_registry() { + static OID_Map g_map; + return g_map; + } + + private: + OID_Map() { + m_str2oid = OIDS::load_str2oid_map(); + m_oid2str = OIDS::load_oid2str_map(); + } + + mutex_type m_mutex; + std::unordered_map m_str2oid; + std::unordered_map m_oid2str; +}; + +} // namespace + +void OIDS::add_oid(const OID& oid, const std::string& name) { + OID_Map::global_registry().add_oid(oid, name); +} + +void OIDS::add_oidstr(const char* oidstr, const char* name) { add_oid(OID(oidstr), name); } + +void OIDS::add_oid2str(const OID& oid, const std::string& name) { + OID_Map::global_registry().add_oid2str(oid, name); +} + +void OIDS::add_str2oid(const OID& oid, const std::string& name) { + OID_Map::global_registry().add_str2oid(oid, name); +} + +std::string OIDS::oid2str_or_empty(const OID& oid) { + return OID_Map::global_registry().oid2str(oid); +} + +OID OIDS::str2oid_or_empty(const std::string& name) { + return OID_Map::global_registry().str2oid(name); +} + +std::string OIDS::oid2str_or_throw(const OID& oid) { + const std::string s = OIDS::oid2str_or_empty(oid); + if (s.empty()) throw Lookup_Error("No name associated with OID " + oid.to_string()); + return s; +} + +bool OIDS::have_oid(const std::string& name) { return OID_Map::global_registry().have_oid(name); } + +} // namespace Botan +/* + * (C) 2019 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +void Buffered_Computation::update_be(uint16_t val) { + uint8_t inb[sizeof(val)]; + store_be(val, inb); + add_data(inb, sizeof(inb)); +} + +void Buffered_Computation::update_be(uint32_t val) { + uint8_t inb[sizeof(val)]; + store_be(val, inb); + add_data(inb, sizeof(inb)); +} + +void Buffered_Computation::update_be(uint64_t val) { + uint8_t inb[sizeof(val)]; + store_be(val, inb); + add_data(inb, sizeof(inb)); +} + +void Buffered_Computation::update_le(uint16_t val) { + uint8_t inb[sizeof(val)]; + store_le(val, inb); + add_data(inb, sizeof(inb)); +} + +void Buffered_Computation::update_le(uint32_t val) { + uint8_t inb[sizeof(val)]; + store_le(val, inb); + add_data(inb, sizeof(inb)); +} + +void Buffered_Computation::update_le(uint64_t val) { + uint8_t inb[sizeof(val)]; + store_le(val, inb); + add_data(inb, sizeof(inb)); +} + +} // namespace Botan +/* + * SCAN Name Abstraction + * (C) 2008-2009,2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +namespace { + +std::string make_arg(const std::vector>& name, size_t start) { + std::string output = name[start].second; + size_t level = name[start].first; + + size_t paren_depth = 0; + + for (size_t i = start + 1; i != name.size(); ++i) { + if (name[i].first <= name[start].first) break; + + if (name[i].first > level) { + output += "(" + name[i].second; + ++paren_depth; + } else if (name[i].first < level) { + output += ")," + name[i].second; + --paren_depth; + } else { + if (output[output.size() - 1] != '(') output += ","; + output += name[i].second; + } + + level = name[i].first; + } + + for (size_t i = 0; i != paren_depth; ++i) output += ")"; + + return output; +} + +} // namespace + +SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec)) {} + +SCAN_Name::SCAN_Name(std::string algo_spec) + : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info() { + if (algo_spec.size() == 0) throw Invalid_Argument("Expected algorithm name, got empty string"); + + std::vector> name; + size_t level = 0; + std::pair accum = std::make_pair(level, ""); + + const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': "; + + for (size_t i = 0; i != algo_spec.size(); ++i) { + char c = algo_spec[i]; + + if (c == '/' || c == ',' || c == '(' || c == ')') { + if (c == '(') + ++level; + else if (c == ')') { + if (level == 0) throw Decoding_Error(decoding_error + "Mismatched parens"); + --level; + } + + if (c == '/' && level > 0) + accum.second.push_back(c); + else { + if (accum.second != "") name.push_back(accum); + accum = std::make_pair(level, ""); + } + } else + accum.second.push_back(c); + } + + if (accum.second != "") name.push_back(accum); + + if (level != 0) throw Decoding_Error(decoding_error + "Missing close paren"); + + if (name.size() == 0) throw Decoding_Error(decoding_error + "Empty name"); + + m_alg_name = name[0].second; + + bool in_modes = false; + + for (size_t i = 1; i != name.size(); ++i) { + if (name[i].first == 0) { + m_mode_info.push_back(make_arg(name, i)); + in_modes = true; + } else if (name[i].first == 1 && !in_modes) + m_args.push_back(make_arg(name, i)); + } +} + +std::string SCAN_Name::arg(size_t i) const { + if (i >= arg_count()) + throw Invalid_Argument("SCAN_Name::arg " + std::to_string(i) + " out of range for '" + + to_string() + "'"); + return m_args[i]; +} + +std::string SCAN_Name::arg(size_t i, const std::string& def_value) const { + if (i >= arg_count()) return def_value; + return m_args[i]; +} + +size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const { + if (i >= arg_count()) return def_value; + return to_u32bit(m_args[i]); +} + +} // namespace Botan +/* + * (C) 2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +void SymmetricAlgorithm::throw_key_not_set_error() const { throw Key_Not_Set(name()); } + +void SymmetricAlgorithm::set_key(const uint8_t key[], size_t length) { + if (!valid_keylength(length)) throw Invalid_Key_Length(name(), length); + key_schedule(key, length); +} + +} // namespace Botan +/* + * OctetString + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +/* + * Create an OctetString from RNG output + */ +OctetString::OctetString(RandomNumberGenerator& rng, size_t len) { rng.random_vec(m_data, len); } + +/* + * Create an OctetString from a hex string + */ +OctetString::OctetString(const std::string& hex_string) { + if (!hex_string.empty()) { + m_data.resize(1 + hex_string.length() / 2); + m_data.resize(hex_decode(m_data.data(), hex_string)); + } +} + +/* + * Create an OctetString from a byte string + */ +OctetString::OctetString(const uint8_t in[], size_t n) { m_data.assign(in, in + n); } + +/* + * Set the parity of each key byte to odd + */ +void OctetString::set_odd_parity() { + const uint8_t ODD_PARITY[256] = { + 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, 0x08, 0x08, 0x0B, 0x0B, 0x0D, 0x0D, 0x0E, + 0x0E, 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16, 0x19, 0x19, 0x1A, 0x1A, 0x1C, 0x1C, + 0x1F, 0x1F, 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26, 0x29, 0x29, 0x2A, 0x2A, 0x2C, + 0x2C, 0x2F, 0x2F, 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, 0x38, 0x38, 0x3B, 0x3B, + 0x3D, 0x3D, 0x3E, 0x3E, 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46, 0x49, 0x49, 0x4A, + 0x4A, 0x4C, 0x4C, 0x4F, 0x4F, 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57, 0x58, 0x58, + 0x5B, 0x5B, 0x5D, 0x5D, 0x5E, 0x5E, 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, 0x68, + 0x68, 0x6B, 0x6B, 0x6D, 0x6D, 0x6E, 0x6E, 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76, + 0x79, 0x79, 0x7A, 0x7A, 0x7C, 0x7C, 0x7F, 0x7F, 0x80, 0x80, 0x83, 0x83, 0x85, 0x85, 0x86, + 0x86, 0x89, 0x89, 0x8A, 0x8A, 0x8C, 0x8C, 0x8F, 0x8F, 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, + 0x97, 0x97, 0x98, 0x98, 0x9B, 0x9B, 0x9D, 0x9D, 0x9E, 0x9E, 0xA1, 0xA1, 0xA2, 0xA2, 0xA4, + 0xA4, 0xA7, 0xA7, 0xA8, 0xA8, 0xAB, 0xAB, 0xAD, 0xAD, 0xAE, 0xAE, 0xB0, 0xB0, 0xB3, 0xB3, + 0xB5, 0xB5, 0xB6, 0xB6, 0xB9, 0xB9, 0xBA, 0xBA, 0xBC, 0xBC, 0xBF, 0xBF, 0xC1, 0xC1, 0xC2, + 0xC2, 0xC4, 0xC4, 0xC7, 0xC7, 0xC8, 0xC8, 0xCB, 0xCB, 0xCD, 0xCD, 0xCE, 0xCE, 0xD0, 0xD0, + 0xD3, 0xD3, 0xD5, 0xD5, 0xD6, 0xD6, 0xD9, 0xD9, 0xDA, 0xDA, 0xDC, 0xDC, 0xDF, 0xDF, 0xE0, + 0xE0, 0xE3, 0xE3, 0xE5, 0xE5, 0xE6, 0xE6, 0xE9, 0xE9, 0xEA, 0xEA, 0xEC, 0xEC, 0xEF, 0xEF, + 0xF1, 0xF1, 0xF2, 0xF2, 0xF4, 0xF4, 0xF7, 0xF7, 0xF8, 0xF8, 0xFB, 0xFB, 0xFD, 0xFD, 0xFE, + 0xFE}; + + for (size_t j = 0; j != m_data.size(); ++j) m_data[j] = ODD_PARITY[m_data[j]]; +} + +/* + * Hex encode an OctetString + */ +std::string OctetString::to_string() const { return hex_encode(m_data.data(), m_data.size()); } + +/* + * XOR Operation for OctetStrings + */ +OctetString& OctetString::operator^=(const OctetString& k) { + if (&k == this) { + zeroise(m_data); + return (*this); + } + xor_buf(m_data.data(), k.begin(), std::min(length(), k.length())); + return (*this); +} + +/* + * Equality Operation for OctetStrings + */ +bool operator==(const OctetString& s1, const OctetString& s2) { + return (s1.bits_of() == s2.bits_of()); +} + +/* + * Unequality Operation for OctetStrings + */ +bool operator!=(const OctetString& s1, const OctetString& s2) { return !(s1 == s2); } + +/* + * Append Operation for OctetStrings + */ +OctetString operator+(const OctetString& k1, const OctetString& k2) { + secure_vector out; + out += k1.bits_of(); + out += k2.bits_of(); + return OctetString(out); +} + +/* + * XOR Operation for OctetStrings + */ +OctetString operator^(const OctetString& k1, const OctetString& k2) { + secure_vector out(std::max(k1.length(), k2.length())); + + copy_mem(out.data(), k1.begin(), k1.length()); + xor_buf(out.data(), k2.begin(), k2.length()); + return OctetString(out); +} + +} // namespace Botan +/* + * Base64 Encoding and Decoding + * (C) 2010,2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +namespace { + +class Base64 final { + public: + static inline std::string name() noexcept { return "base64"; } + + static inline size_t encoding_bytes_in() noexcept { return m_encoding_bytes_in; } + static inline size_t encoding_bytes_out() noexcept { return m_encoding_bytes_out; } + + static inline size_t decoding_bytes_in() noexcept { return m_encoding_bytes_out; } + static inline size_t decoding_bytes_out() noexcept { return m_encoding_bytes_in; } + + static inline size_t bits_consumed() noexcept { return m_encoding_bits; } + static inline size_t remaining_bits_before_padding() noexcept { + return m_remaining_bits_before_padding; + } + + static inline size_t encode_max_output(size_t input_length) { + return (round_up(input_length, m_encoding_bytes_in) / m_encoding_bytes_in) * + m_encoding_bytes_out; + } + static inline size_t decode_max_output(size_t input_length) { + return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / + m_encoding_bytes_out; + } + + static void encode(char out[8], const uint8_t in[5]) noexcept { + out[0] = Base64::m_bin_to_base64[(in[0] & 0xFC) >> 2]; + out[1] = Base64::m_bin_to_base64[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + out[2] = Base64::m_bin_to_base64[((in[1] & 0x0F) << 2) | (in[2] >> 6)]; + out[3] = Base64::m_bin_to_base64[in[2] & 0x3F]; + } + + static inline uint8_t lookup_binary_value(char input) noexcept { + return Base64::m_base64_to_bin[static_cast(input)]; + } + + static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws) { + if (bin <= 0x3F) { + return true; + } else if (!(bin == 0x81 || (bin == 0x80 && ignore_ws))) { + std::string bad_char(1, input); + if (bad_char == "\t") { + bad_char = "\\t"; + } else if (bad_char == "\n") { + bad_char = "\\n"; + } else if (bad_char == "\r") { + bad_char = "\\r"; + } + + throw Invalid_Argument(std::string("base64_decode: invalid base64 character '") + + bad_char + "'"); + } + return false; + } + + static void decode(uint8_t* out_ptr, const uint8_t decode_buf[4]) { + out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4); + out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2); + out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3]; + } + + static inline size_t bytes_to_remove(size_t final_truncate) { return final_truncate; } + + private: + static const size_t m_encoding_bits = 6; + static const size_t m_remaining_bits_before_padding = 8; + + static const size_t m_encoding_bytes_in = 3; + static const size_t m_encoding_bytes_out = 4; + + static const uint8_t m_bin_to_base64[64]; + static const uint8_t m_base64_to_bin[256]; +}; + +const uint8_t Base64::m_bin_to_base64[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; + +/* + * base64 Decoder Lookup Table + * Warning: assumes ASCII encodings + */ +const uint8_t Base64::m_base64_to_bin[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, + 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +} // namespace + +size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t& input_consumed, + bool final_inputs) { + return base_encode(Base64(), out, in, input_length, input_consumed, final_inputs); +} + +std::string base64_encode(const uint8_t input[], size_t input_length) { + return base_encode_to_string(Base64(), input, input_length); +} + +size_t base64_decode(uint8_t out[], const char in[], size_t input_length, size_t& input_consumed, + bool final_inputs, bool ignore_ws) { + return base_decode(Base64(), out, in, input_length, input_consumed, final_inputs, ignore_ws); +} + +size_t base64_decode(uint8_t output[], const char input[], size_t input_length, bool ignore_ws) { + return base_decode_full(Base64(), output, input, input_length, ignore_ws); +} + +size_t base64_decode(uint8_t output[], const std::string& input, bool ignore_ws) { + return base64_decode(output, input.data(), input.length(), ignore_ws); +} + +secure_vector base64_decode(const char input[], size_t input_length, bool ignore_ws) { + return base_decode_to_vec>(Base64(), input, input_length, ignore_ws); +} + +secure_vector base64_decode(const std::string& input, bool ignore_ws) { + return base64_decode(input.data(), input.size(), ignore_ws); +} + +size_t base64_encode_max_output(size_t input_length) { + return Base64::encode_max_output(input_length); +} + +size_t base64_decode_max_output(size_t input_length) { + return Base64::decode_max_output(input_length); +} + +} // namespace Botan +/* + * BigInt Encoding/Decoding + * (C) 1999-2010,2012,2019 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +namespace Botan { + +std::string BigInt::to_dec_string() const { + BigInt copy = *this; + copy.set_sign(Positive); + + uint8_t remainder; + std::vector digits; + + while (copy > 0) { + ct_divide_u8(copy, 10, copy, remainder); + digits.push_back(remainder); + } + + std::string s; + + for (auto i = digits.rbegin(); i != digits.rend(); ++i) { + s.push_back(Charset::digit2char(*i)); + } + + if (s.empty()) s += "0"; + + return s; +} + +std::string BigInt::to_hex_string() const { + const std::vector bits = BigInt::encode(*this); + if (bits.empty()) + return "00"; + else + return hex_encode(bits); +} + +/* + * Encode a BigInt + */ +void BigInt::encode(uint8_t output[], const BigInt& n, Base base) { + secure_vector enc = n.encode_locked(base); + copy_mem(output, enc.data(), enc.size()); +} + +namespace { + +std::vector str_to_vector(const std::string& s) { + std::vector v(s.size()); + std::memcpy(v.data(), s.data(), s.size()); + return v; +} + +secure_vector str_to_lvector(const std::string& s) { + secure_vector v(s.size()); + std::memcpy(v.data(), s.data(), s.size()); + return v; +} + +} // namespace + +/* + * Encode a BigInt + */ +std::vector BigInt::encode(const BigInt& n, Base base) { + if (base == Binary) + return BigInt::encode(n); + else if (base == Hexadecimal) + return str_to_vector(n.to_hex_string()); + else if (base == Decimal) + return str_to_vector(n.to_dec_string()); + else + throw Invalid_Argument("Unknown BigInt encoding base"); +} + +/* + * Encode a BigInt + */ +secure_vector BigInt::encode_locked(const BigInt& n, Base base) { + if (base == Binary) + return BigInt::encode_locked(n); + else if (base == Hexadecimal) + return str_to_lvector(n.to_hex_string()); + else if (base == Decimal) + return str_to_lvector(n.to_dec_string()); + else + throw Invalid_Argument("Unknown BigInt encoding base"); +} + +/* + * Encode a BigInt, with leading 0s if needed + */ +secure_vector BigInt::encode_1363(const BigInt& n, size_t bytes) { + if (n.bytes() > bytes) throw Encoding_Error("encode_1363: n is too large to encode properly"); + + secure_vector output(bytes); + n.binary_encode(output.data(), output.size()); + return output; +} + +// static +void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n) { + if (n.bytes() > bytes) throw Encoding_Error("encode_1363: n is too large to encode properly"); + + n.binary_encode(output, bytes); +} + +/* + * Encode two BigInt, with leading 0s if needed, and concatenate + */ +secure_vector BigInt::encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, + size_t bytes) { + if (n1.bytes() > bytes || n2.bytes() > bytes) + throw Encoding_Error("encode_fixed_length_int_pair: values too large to encode properly"); + secure_vector output(2 * bytes); + n1.binary_encode(output.data(), bytes); + n2.binary_encode(output.data() + bytes, bytes); + return output; +} + +/* + * Decode a BigInt + */ +BigInt BigInt::decode(const uint8_t buf[], size_t length, Base base) { + BigInt r; + if (base == Binary) { + r.binary_decode(buf, length); + } else if (base == Hexadecimal) { + secure_vector binary; + + if (length % 2) { + // Handle lack of leading 0 + const char buf0_with_leading_0[2] = {'0', static_cast(buf[0])}; + + binary = hex_decode_locked(buf0_with_leading_0, 2); + + binary += hex_decode_locked(cast_uint8_ptr_to_char(&buf[1]), length - 1, false); + } else + binary = hex_decode_locked(cast_uint8_ptr_to_char(buf), length, false); + + r.binary_decode(binary.data(), binary.size()); + } else if (base == Decimal) { + for (size_t i = 0; i != length; ++i) { + if (Charset::is_space(buf[i])) continue; + + if (!Charset::is_digit(buf[i])) + throw Invalid_Argument( + "BigInt::decode: " + "Invalid character in decimal input"); + + const uint8_t x = Charset::char2digit(buf[i]); + + if (x >= 10) throw Invalid_Argument("BigInt: Invalid decimal string"); + + r *= 10; + r += x; + } + } else + throw Invalid_Argument("Unknown BigInt decoding method"); + return r; +} + +} // namespace Botan +/* + * BigInt Input/Output + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #include namespace Botan { /* -* Write the BigInt into a stream -*/ -std::ostream& operator<<(std::ostream& stream, const BigInt& n) - { - size_t base = 10; - if(stream.flags() & std::ios::hex) - base = 16; - if(stream.flags() & std::ios::oct) - throw Invalid_Argument("Octal output of BigInt not supported"); + * Write the BigInt into a stream + */ +std::ostream& operator<<(std::ostream& stream, const BigInt& n) { + size_t base = 10; + if (stream.flags() & std::ios::hex) base = 16; + if (stream.flags() & std::ios::oct) + throw Invalid_Argument("Octal output of BigInt not supported"); - if(n == 0) - stream.write("0", 1); - else - { - if(n < 0) - stream.write("-", 1); + if (n == 0) + stream.write("0", 1); + else { + if (n < 0) stream.write("-", 1); - std::string enc; + std::string enc; - if(base == 10) - enc = n.to_dec_string(); - else - enc = n.to_hex_string(); - - size_t skip = 0; - while(skip < enc.size() && enc[skip] == '0') - ++skip; - stream.write(&enc[skip], enc.size() - skip); - } - if(!stream.good()) - throw Stream_IO_Error("BigInt output operator has failed"); - return stream; - } - -/* -* Read the BigInt from a stream -*/ -std::istream& operator>>(std::istream& stream, BigInt& n) - { - std::string str; - std::getline(stream, str); - if(stream.bad() || (stream.fail() && !stream.eof())) - throw Stream_IO_Error("BigInt input operator has failed"); - n = BigInt(str); - return stream; - } + if (base == 10) + enc = n.to_dec_string(); + else + enc = n.to_hex_string(); + size_t skip = 0; + while (skip < enc.size() && enc[skip] == '0') ++skip; + stream.write(&enc[skip], enc.size() - skip); + } + if (!stream.good()) throw Stream_IO_Error("BigInt output operator has failed"); + return stream; } -/* -* (C) 1999-2007,2018 Jack Lloyd -* 2016 Matthias Gierlings -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Read the BigInt from a stream + */ +std::istream& operator>>(std::istream& stream, BigInt& n) { + std::string str; + std::getline(stream, str); + if (stream.bad() || (stream.fail() && !stream.eof())) + throw Stream_IO_Error("BigInt input operator has failed"); + n = BigInt(str); + return stream; +} + +} // namespace Botan +/* + * (C) 1999-2007,2018 Jack Lloyd + * 2016 Matthias Gierlings + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -BigInt& BigInt::add(const word y[], size_t y_words, Sign y_sign) - { - const size_t x_sw = sig_words(); +BigInt& BigInt::add(const word y[], size_t y_words, Sign y_sign) { + const size_t x_sw = sig_words(); - grow_to(std::max(x_sw, y_words) + 1); + grow_to(std::max(x_sw, y_words) + 1); - if(sign() == y_sign) - { - bigint_add2(mutable_data(), size() - 1, y, y_words); - } - else - { - const int32_t relative_size = bigint_cmp(data(), x_sw, y, y_words); + if (sign() == y_sign) { + bigint_add2(mutable_data(), size() - 1, y, y_words); + } else { + const int32_t relative_size = bigint_cmp(data(), x_sw, y, y_words); - if(relative_size >= 0) - { - // *this >= y - bigint_sub2(mutable_data(), x_sw, y, y_words); - } - else - { - // *this < y - bigint_sub2_rev(mutable_data(), y, y_words); - } + if (relative_size >= 0) { + // *this >= y + bigint_sub2(mutable_data(), x_sw, y, y_words); + } else { + // *this < y + bigint_sub2_rev(mutable_data(), y, y_words); + } - //this->sign_fixup(relative_size, y_sign); - if(relative_size < 0) - set_sign(y_sign); - else if(relative_size == 0) - set_sign(Positive); - } + // this->sign_fixup(relative_size, y_sign); + if (relative_size < 0) + set_sign(y_sign); + else if (relative_size == 0) + set_sign(Positive); + } - return (*this); - } + return (*this); +} -BigInt& BigInt::mod_add(const BigInt& s, const BigInt& mod, secure_vector& ws) - { - if(this->is_negative() || s.is_negative() || mod.is_negative()) - throw Invalid_Argument("BigInt::mod_add expects all arguments are positive"); +BigInt& BigInt::mod_add(const BigInt& s, const BigInt& mod, secure_vector& ws) { + if (this->is_negative() || s.is_negative() || mod.is_negative()) + throw Invalid_Argument("BigInt::mod_add expects all arguments are positive"); - BOTAN_DEBUG_ASSERT(*this < mod); - BOTAN_DEBUG_ASSERT(s < mod); + BOTAN_DEBUG_ASSERT(*this < mod); + BOTAN_DEBUG_ASSERT(s < mod); - /* - t + s or t + s - p == t - (p - s) + /* + t + s or t + s - p == t - (p - s) - So first compute ws = p - s + So first compute ws = p - s - Then compute t + s and t - ws + Then compute t + s and t - ws - If t - ws does not borrow, then that is the correct valued - */ + If t - ws does not borrow, then that is the correct valued + */ - const size_t mod_sw = mod.sig_words(); - BOTAN_ARG_CHECK(mod_sw > 0, "BigInt::mod_add modulus must be positive"); + const size_t mod_sw = mod.sig_words(); + BOTAN_ARG_CHECK(mod_sw > 0, "BigInt::mod_add modulus must be positive"); - this->grow_to(mod_sw); - s.grow_to(mod_sw); + this->grow_to(mod_sw); + s.grow_to(mod_sw); - // First mod_sw for p - s, 2*mod_sw for bigint_addsub workspace - if(ws.size() < 3*mod_sw) - ws.resize(3*mod_sw); + // First mod_sw for p - s, 2*mod_sw for bigint_addsub workspace + if (ws.size() < 3 * mod_sw) ws.resize(3 * mod_sw); - word borrow = bigint_sub3(&ws[0], mod.data(), mod_sw, s.data(), mod_sw); - BOTAN_DEBUG_ASSERT(borrow == 0); + word borrow = bigint_sub3(&ws[0], mod.data(), mod_sw, s.data(), mod_sw); + BOTAN_DEBUG_ASSERT(borrow == 0); - // Compute t - ws - borrow = bigint_sub3(&ws[mod_sw], this->data(), mod_sw, &ws[0], mod_sw); + // Compute t - ws + borrow = bigint_sub3(&ws[mod_sw], this->data(), mod_sw, &ws[0], mod_sw); - // Compute t + s - bigint_add3_nc(&ws[mod_sw*2], this->data(), mod_sw, s.data(), mod_sw); + // Compute t + s + bigint_add3_nc(&ws[mod_sw * 2], this->data(), mod_sw, s.data(), mod_sw); - CT::conditional_copy_mem(borrow, &ws[0], &ws[mod_sw*2], &ws[mod_sw], mod_sw); - set_words(&ws[0], mod_sw); + CT::conditional_copy_mem(borrow, &ws[0], &ws[mod_sw * 2], &ws[mod_sw], mod_sw); + set_words(&ws[0], mod_sw); - return (*this); - } + return (*this); +} -BigInt& BigInt::mod_sub(const BigInt& s, const BigInt& mod, secure_vector& ws) - { - if(this->is_negative() || s.is_negative() || mod.is_negative()) - throw Invalid_Argument("BigInt::mod_sub expects all arguments are positive"); +BigInt& BigInt::mod_sub(const BigInt& s, const BigInt& mod, secure_vector& ws) { + if (this->is_negative() || s.is_negative() || mod.is_negative()) + throw Invalid_Argument("BigInt::mod_sub expects all arguments are positive"); - // We are assuming in this function that *this and s are no more than mod_sw words long - BOTAN_DEBUG_ASSERT(*this < mod); - BOTAN_DEBUG_ASSERT(s < mod); + // We are assuming in this function that *this and s are no more than mod_sw words long + BOTAN_DEBUG_ASSERT(*this < mod); + BOTAN_DEBUG_ASSERT(s < mod); - const size_t mod_sw = mod.sig_words(); + const size_t mod_sw = mod.sig_words(); - this->grow_to(mod_sw); - s.grow_to(mod_sw); + this->grow_to(mod_sw); + s.grow_to(mod_sw); - if(ws.size() < mod_sw) - ws.resize(mod_sw); + if (ws.size() < mod_sw) ws.resize(mod_sw); #if 0 //Faster but not const time: @@ -4720,1232 +3928,1050 @@ BigInt& BigInt::mod_sub(const BigInt& s, const BigInt& mod, secure_vector& swap_reg(ws); } #else - if(mod_sw == 4) - bigint_mod_sub_n<4>(mutable_data(), s.data(), mod.data(), ws.data()); - else if(mod_sw == 6) - bigint_mod_sub_n<6>(mutable_data(), s.data(), mod.data(), ws.data()); - else - bigint_mod_sub(mutable_data(), s.data(), mod.data(), mod_sw, ws.data()); + if (mod_sw == 4) + bigint_mod_sub_n<4>(mutable_data(), s.data(), mod.data(), ws.data()); + else if (mod_sw == 6) + bigint_mod_sub_n<6>(mutable_data(), s.data(), mod.data(), ws.data()); + else + bigint_mod_sub(mutable_data(), s.data(), mod.data(), mod_sw, ws.data()); #endif - return (*this); - } - -BigInt& BigInt::mod_mul(uint8_t y, const BigInt& mod, secure_vector& ws) - { - BOTAN_ARG_CHECK(this->is_negative() == false, "*this must be positive"); - BOTAN_ARG_CHECK(y < 16, "y too large"); - - BOTAN_DEBUG_ASSERT(*this < mod); - - switch(y) - { - case 2: - *this <<= 1; - break; - case 4: - *this <<= 2; - break; - case 8: - *this <<= 3; - break; - default: - *this *= static_cast(y); - break; - } - - this->reduce_below(mod, ws); - return (*this); - } - -BigInt& BigInt::rev_sub(const word y[], size_t y_sw, secure_vector& ws) - { - if(this->sign() != BigInt::Positive) - throw Invalid_State("BigInt::sub_rev requires this is positive"); - - const size_t x_sw = this->sig_words(); - - ws.resize(std::max(x_sw, y_sw)); - clear_mem(ws.data(), ws.size()); - - const int32_t relative_size = bigint_sub_abs(ws.data(), data(), x_sw, y, y_sw); - - this->cond_flip_sign(relative_size > 0); - this->swap_reg(ws); - - return (*this); - } - -/* -* Multiplication Operator -*/ -BigInt& BigInt::operator*=(const BigInt& y) - { - secure_vector ws; - return this->mul(y, ws); - } - -BigInt& BigInt::mul(const BigInt& y, secure_vector& ws) - { - const size_t x_sw = sig_words(); - const size_t y_sw = y.sig_words(); - set_sign((sign() == y.sign()) ? Positive : Negative); - - if(x_sw == 0 || y_sw == 0) - { - clear(); - set_sign(Positive); - } - else if(x_sw == 1 && y_sw) - { - grow_to(y_sw + 1); - bigint_linmul3(mutable_data(), y.data(), y_sw, word_at(0)); - } - else if(y_sw == 1 && x_sw) - { - word carry = bigint_linmul2(mutable_data(), x_sw, y.word_at(0)); - set_word_at(x_sw, carry); - } - else - { - const size_t new_size = x_sw + y_sw + 1; - ws.resize(new_size); - secure_vector z_reg(new_size); - - bigint_mul(z_reg.data(), z_reg.size(), - data(), size(), x_sw, - y.data(), y.size(), y_sw, - ws.data(), ws.size()); - - this->swap_reg(z_reg); - } - - return (*this); - } - -BigInt& BigInt::square(secure_vector& ws) - { - const size_t sw = sig_words(); - - secure_vector z(2*sw); - ws.resize(z.size()); - - bigint_sqr(z.data(), z.size(), - data(), size(), sw, - ws.data(), ws.size()); - - swap_reg(z); - set_sign(BigInt::Positive); - - return (*this); - } - -BigInt& BigInt::operator*=(word y) - { - if(y == 0) - { - clear(); - set_sign(Positive); - } - - const word carry = bigint_linmul2(mutable_data(), size(), y); - set_word_at(size(), carry); - - return (*this); - } - -/* -* Division Operator -*/ -BigInt& BigInt::operator/=(const BigInt& y) - { - if(y.sig_words() == 1 && is_power_of_2(y.word_at(0))) - (*this) >>= (y.bits() - 1); - else - (*this) = (*this) / y; - return (*this); - } - -/* -* Modulo Operator -*/ -BigInt& BigInt::operator%=(const BigInt& mod) - { - return (*this = (*this) % mod); - } - -/* -* Modulo Operator -*/ -word BigInt::operator%=(word mod) - { - if(mod == 0) - throw BigInt::DivideByZero(); - - word remainder = 0; - - if(is_power_of_2(mod)) - { - remainder = (word_at(0) & (mod - 1)); - } - else - { - const size_t sw = sig_words(); - for(size_t i = sw; i > 0; --i) - remainder = bigint_modop(remainder, word_at(i-1), mod); - } - - if(remainder && sign() == BigInt::Negative) - remainder = mod - remainder; - - m_data.set_to_zero(); - m_data.set_word_at(0, remainder); - set_sign(BigInt::Positive); - return remainder; - } - -/* -* Left Shift Operator -*/ -BigInt& BigInt::operator<<=(size_t shift) - { - const size_t shift_words = shift / BOTAN_MP_WORD_BITS; - const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; - const size_t size = sig_words(); - - const size_t bits_free = top_bits_free(); - - const size_t new_size = size + shift_words + (bits_free < shift_bits); - - m_data.grow_to(new_size); - - bigint_shl1(m_data.mutable_data(), new_size, size, shift_words, shift_bits); - - return (*this); - } - -/* -* Right Shift Operator -*/ -BigInt& BigInt::operator>>=(size_t shift) - { - const size_t shift_words = shift / BOTAN_MP_WORD_BITS; - const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; - - bigint_shr1(m_data.mutable_data(), m_data.size(), shift_words, shift_bits); - - if(is_negative() && is_zero()) - set_sign(Positive); - - return (*this); - } - + return (*this); } -/* -* BigInt Binary Operators -* (C) 1999-2007,2018 Jack Lloyd -* 2016 Matthias Gierlings -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +BigInt& BigInt::mod_mul(uint8_t y, const BigInt& mod, secure_vector& ws) { + BOTAN_ARG_CHECK(this->is_negative() == false, "*this must be positive"); + BOTAN_ARG_CHECK(y < 16, "y too large"); + + BOTAN_DEBUG_ASSERT(*this < mod); + + switch (y) { + case 2: + *this <<= 1; + break; + case 4: + *this <<= 2; + break; + case 8: + *this <<= 3; + break; + default: + *this *= static_cast(y); + break; + } + + this->reduce_below(mod, ws); + return (*this); +} + +BigInt& BigInt::rev_sub(const word y[], size_t y_sw, secure_vector& ws) { + if (this->sign() != BigInt::Positive) + throw Invalid_State("BigInt::sub_rev requires this is positive"); + + const size_t x_sw = this->sig_words(); + + ws.resize(std::max(x_sw, y_sw)); + clear_mem(ws.data(), ws.size()); + + const int32_t relative_size = bigint_sub_abs(ws.data(), data(), x_sw, y, y_sw); + + this->cond_flip_sign(relative_size > 0); + this->swap_reg(ws); + + return (*this); +} + +/* + * Multiplication Operator + */ +BigInt& BigInt::operator*=(const BigInt& y) { + secure_vector ws; + return this->mul(y, ws); +} + +BigInt& BigInt::mul(const BigInt& y, secure_vector& ws) { + const size_t x_sw = sig_words(); + const size_t y_sw = y.sig_words(); + set_sign((sign() == y.sign()) ? Positive : Negative); + + if (x_sw == 0 || y_sw == 0) { + clear(); + set_sign(Positive); + } else if (x_sw == 1 && y_sw) { + grow_to(y_sw + 1); + bigint_linmul3(mutable_data(), y.data(), y_sw, word_at(0)); + } else if (y_sw == 1 && x_sw) { + word carry = bigint_linmul2(mutable_data(), x_sw, y.word_at(0)); + set_word_at(x_sw, carry); + } else { + const size_t new_size = x_sw + y_sw + 1; + ws.resize(new_size); + secure_vector z_reg(new_size); + + bigint_mul(z_reg.data(), z_reg.size(), data(), size(), x_sw, y.data(), y.size(), y_sw, + ws.data(), ws.size()); + + this->swap_reg(z_reg); + } + + return (*this); +} + +BigInt& BigInt::square(secure_vector& ws) { + const size_t sw = sig_words(); + + secure_vector z(2 * sw); + ws.resize(z.size()); + + bigint_sqr(z.data(), z.size(), data(), size(), sw, ws.data(), ws.size()); + + swap_reg(z); + set_sign(BigInt::Positive); + + return (*this); +} + +BigInt& BigInt::operator*=(word y) { + if (y == 0) { + clear(); + set_sign(Positive); + } + + const word carry = bigint_linmul2(mutable_data(), size(), y); + set_word_at(size(), carry); + + return (*this); +} + +/* + * Division Operator + */ +BigInt& BigInt::operator/=(const BigInt& y) { + if (y.sig_words() == 1 && is_power_of_2(y.word_at(0))) + (*this) >>= (y.bits() - 1); + else + (*this) = (*this) / y; + return (*this); +} + +/* + * Modulo Operator + */ +BigInt& BigInt::operator%=(const BigInt& mod) { return (*this = (*this) % mod); } + +/* + * Modulo Operator + */ +word BigInt::operator%=(word mod) { + if (mod == 0) throw BigInt::DivideByZero(); + + word remainder = 0; + + if (is_power_of_2(mod)) { + remainder = (word_at(0) & (mod - 1)); + } else { + const size_t sw = sig_words(); + for (size_t i = sw; i > 0; --i) remainder = bigint_modop(remainder, word_at(i - 1), mod); + } + + if (remainder && sign() == BigInt::Negative) remainder = mod - remainder; + + m_data.set_to_zero(); + m_data.set_word_at(0, remainder); + set_sign(BigInt::Positive); + return remainder; +} + +/* + * Left Shift Operator + */ +BigInt& BigInt::operator<<=(size_t shift) { + const size_t shift_words = shift / BOTAN_MP_WORD_BITS; + const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; + const size_t size = sig_words(); + + const size_t bits_free = top_bits_free(); + + const size_t new_size = size + shift_words + (bits_free < shift_bits); + + m_data.grow_to(new_size); + + bigint_shl1(m_data.mutable_data(), new_size, size, shift_words, shift_bits); + + return (*this); +} + +/* + * Right Shift Operator + */ +BigInt& BigInt::operator>>=(size_t shift) { + const size_t shift_words = shift / BOTAN_MP_WORD_BITS; + const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; + + bigint_shr1(m_data.mutable_data(), m_data.size(), shift_words, shift_bits); + + if (is_negative() && is_zero()) set_sign(Positive); + + return (*this); +} + +} // namespace Botan +/* + * BigInt Binary Operators + * (C) 1999-2007,2018 Jack Lloyd + * 2016 Matthias Gierlings + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -//static -BigInt BigInt::add2(const BigInt& x, const word y[], size_t y_words, BigInt::Sign y_sign) - { - const size_t x_sw = x.sig_words(); +// static +BigInt BigInt::add2(const BigInt& x, const word y[], size_t y_words, BigInt::Sign y_sign) { + const size_t x_sw = x.sig_words(); - BigInt z(x.sign(), std::max(x_sw, y_words) + 1); + BigInt z(x.sign(), std::max(x_sw, y_words) + 1); - if(x.sign() == y_sign) - { - bigint_add3(z.mutable_data(), x.data(), x_sw, y, y_words); - } - else - { - const int32_t relative_size = bigint_sub_abs(z.mutable_data(), x.data(), x_sw, y, y_words); + if (x.sign() == y_sign) { + bigint_add3(z.mutable_data(), x.data(), x_sw, y, y_words); + } else { + const int32_t relative_size = bigint_sub_abs(z.mutable_data(), x.data(), x_sw, y, y_words); - //z.sign_fixup(relative_size, y_sign); - if(relative_size < 0) - z.set_sign(y_sign); - else if(relative_size == 0) - z.set_sign(BigInt::Positive); - } - - return z; - } - -/* -* Multiplication Operator -*/ -BigInt operator*(const BigInt& x, const BigInt& y) - { - const size_t x_sw = x.sig_words(); - const size_t y_sw = y.sig_words(); - - BigInt z(BigInt::Positive, x.size() + y.size()); - - if(x_sw == 1 && y_sw) - bigint_linmul3(z.mutable_data(), y.data(), y_sw, x.word_at(0)); - else if(y_sw == 1 && x_sw) - bigint_linmul3(z.mutable_data(), x.data(), x_sw, y.word_at(0)); - else if(x_sw && y_sw) - { - secure_vector workspace(z.size()); - - bigint_mul(z.mutable_data(), z.size(), - x.data(), x.size(), x_sw, - y.data(), y.size(), y_sw, - workspace.data(), workspace.size()); - } - - z.cond_flip_sign(x_sw > 0 && y_sw > 0 && x.sign() != y.sign()); - - return z; - } - -/* -* Multiplication Operator -*/ -BigInt operator*(const BigInt& x, word y) - { - const size_t x_sw = x.sig_words(); - - BigInt z(BigInt::Positive, x_sw + 1); - - if(x_sw && y) - { - bigint_linmul3(z.mutable_data(), x.data(), x_sw, y); - z.set_sign(x.sign()); - } - - return z; - } - -/* -* Division Operator -*/ -BigInt operator/(const BigInt& x, const BigInt& y) - { - if(y.sig_words() == 1 && is_power_of_2(y.word_at(0))) - return (x >> (y.bits() - 1)); - - BigInt q, r; - divide(x, y, q, r); - return q; - } - -/* -* Modulo Operator -*/ -BigInt operator%(const BigInt& n, const BigInt& mod) - { - if(mod.is_zero()) - throw BigInt::DivideByZero(); - if(mod.is_negative()) - throw Invalid_Argument("BigInt::operator%: modulus must be > 0"); - if(n.is_positive() && mod.is_positive() && n < mod) - return n; - - BigInt q, r; - divide(n, mod, q, r); - return r; - } - -/* -* Modulo Operator -*/ -word operator%(const BigInt& n, word mod) - { - if(mod == 0) - throw BigInt::DivideByZero(); - - if(mod == 1) - return 0; - - word remainder = 0; - - if(is_power_of_2(mod)) - { - remainder = (n.word_at(0) & (mod - 1)); - } - else - { - const size_t sw = n.sig_words(); - for(size_t i = sw; i > 0; --i) - { - remainder = bigint_modop(remainder, n.word_at(i-1), mod); - } - } - - if(remainder && n.sign() == BigInt::Negative) - return mod - remainder; - return remainder; - } - -/* -* Left Shift Operator -*/ -BigInt operator<<(const BigInt& x, size_t shift) - { - const size_t shift_words = shift / BOTAN_MP_WORD_BITS, - shift_bits = shift % BOTAN_MP_WORD_BITS; - - const size_t x_sw = x.sig_words(); - - BigInt y(x.sign(), x_sw + shift_words + (shift_bits ? 1 : 0)); - bigint_shl2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); - return y; - } - -/* -* Right Shift Operator -*/ -BigInt operator>>(const BigInt& x, size_t shift) - { - const size_t shift_words = shift / BOTAN_MP_WORD_BITS; - const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; - const size_t x_sw = x.sig_words(); - - BigInt y(x.sign(), x_sw - shift_words); - bigint_shr2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); - - if(x.is_negative() && y.is_zero()) - y.set_sign(BigInt::Positive); - - return y; - } + // z.sign_fixup(relative_size, y_sign); + if (relative_size < 0) + z.set_sign(y_sign); + else if (relative_size == 0) + z.set_sign(BigInt::Positive); + } + return z; } -/* -* BigInt Random Generation -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Multiplication Operator + */ +BigInt operator*(const BigInt& x, const BigInt& y) { + const size_t x_sw = x.sig_words(); + const size_t y_sw = y.sig_words(); + + BigInt z(BigInt::Positive, x.size() + y.size()); + + if (x_sw == 1 && y_sw) + bigint_linmul3(z.mutable_data(), y.data(), y_sw, x.word_at(0)); + else if (y_sw == 1 && x_sw) + bigint_linmul3(z.mutable_data(), x.data(), x_sw, y.word_at(0)); + else if (x_sw && y_sw) { + secure_vector workspace(z.size()); + + bigint_mul(z.mutable_data(), z.size(), x.data(), x.size(), x_sw, y.data(), y.size(), y_sw, + workspace.data(), workspace.size()); + } + + z.cond_flip_sign(x_sw > 0 && y_sw > 0 && x.sign() != y.sign()); + + return z; +} + +/* + * Multiplication Operator + */ +BigInt operator*(const BigInt& x, word y) { + const size_t x_sw = x.sig_words(); + + BigInt z(BigInt::Positive, x_sw + 1); + + if (x_sw && y) { + bigint_linmul3(z.mutable_data(), x.data(), x_sw, y); + z.set_sign(x.sign()); + } + + return z; +} + +/* + * Division Operator + */ +BigInt operator/(const BigInt& x, const BigInt& y) { + if (y.sig_words() == 1 && is_power_of_2(y.word_at(0))) return (x >> (y.bits() - 1)); + + BigInt q, r; + divide(x, y, q, r); + return q; +} + +/* + * Modulo Operator + */ +BigInt operator%(const BigInt& n, const BigInt& mod) { + if (mod.is_zero()) throw BigInt::DivideByZero(); + if (mod.is_negative()) throw Invalid_Argument("BigInt::operator%: modulus must be > 0"); + if (n.is_positive() && mod.is_positive() && n < mod) return n; + + BigInt q, r; + divide(n, mod, q, r); + return r; +} + +/* + * Modulo Operator + */ +word operator%(const BigInt& n, word mod) { + if (mod == 0) throw BigInt::DivideByZero(); + + if (mod == 1) return 0; + + word remainder = 0; + + if (is_power_of_2(mod)) { + remainder = (n.word_at(0) & (mod - 1)); + } else { + const size_t sw = n.sig_words(); + for (size_t i = sw; i > 0; --i) { + remainder = bigint_modop(remainder, n.word_at(i - 1), mod); + } + } + + if (remainder && n.sign() == BigInt::Negative) return mod - remainder; + return remainder; +} + +/* + * Left Shift Operator + */ +BigInt operator<<(const BigInt& x, size_t shift) { + const size_t shift_words = shift / BOTAN_MP_WORD_BITS, shift_bits = shift % BOTAN_MP_WORD_BITS; + + const size_t x_sw = x.sig_words(); + + BigInt y(x.sign(), x_sw + shift_words + (shift_bits ? 1 : 0)); + bigint_shl2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); + return y; +} + +/* + * Right Shift Operator + */ +BigInt operator>>(const BigInt& x, size_t shift) { + const size_t shift_words = shift / BOTAN_MP_WORD_BITS; + const size_t shift_bits = shift % BOTAN_MP_WORD_BITS; + const size_t x_sw = x.sig_words(); + + BigInt y(x.sign(), x_sw - shift_words); + bigint_shr2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); + + if (x.is_negative() && y.is_zero()) y.set_sign(BigInt::Positive); + + return y; +} + +} // namespace Botan +/* + * BigInt Random Generation + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Randomize this number -*/ -void BigInt::randomize(RandomNumberGenerator& rng, - size_t bitsize, bool set_high_bit) - { - set_sign(Positive); + * Randomize this number + */ +void BigInt::randomize(RandomNumberGenerator& rng, size_t bitsize, bool set_high_bit) { + set_sign(Positive); - if(bitsize == 0) - { - clear(); - } - else - { - secure_vector array = rng.random_vec(round_up(bitsize, 8) / 8); + if (bitsize == 0) { + clear(); + } else { + secure_vector array = rng.random_vec(round_up(bitsize, 8) / 8); - // Always cut unwanted bits - if(bitsize % 8) - array[0] &= 0xFF >> (8 - (bitsize % 8)); + // Always cut unwanted bits + if (bitsize % 8) array[0] &= 0xFF >> (8 - (bitsize % 8)); - // Set the highest bit if wanted - if (set_high_bit) - array[0] |= 0x80 >> ((bitsize % 8) ? (8 - bitsize % 8) : 0); - - binary_decode(array); - } - } - -/* -* Generate a random integer within given range -*/ -BigInt BigInt::random_integer(RandomNumberGenerator& rng, - const BigInt& min, const BigInt& max) - { - if(min.is_negative() || max.is_negative() || max <= min) - throw Invalid_Argument("BigInt::random_integer invalid range"); - - BigInt r; - - const size_t bits = max.bits(); - - do - { - r.randomize(rng, bits, false); - } - while(r < min || r >= max); - - return r; - } + // Set the highest bit if wanted + if (set_high_bit) array[0] |= 0x80 >> ((bitsize % 8) ? (8 - bitsize % 8) : 0); + binary_decode(array); + } } -/* -* BigInt Base -* (C) 1999-2011,2012,2014,2019 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Generate a random integer within given range + */ +BigInt BigInt::random_integer(RandomNumberGenerator& rng, const BigInt& min, const BigInt& max) { + if (min.is_negative() || max.is_negative() || max <= min) + throw Invalid_Argument("BigInt::random_integer invalid range"); + + BigInt r; + + const size_t bits = max.bits(); + + do { + r.randomize(rng, bits, false); + } while (r < min || r >= max); + + return r; +} + +} // namespace Botan +/* + * BigInt Base + * (C) 1999-2011,2012,2014,2019 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -BigInt::BigInt(const word words[], size_t length) - { - m_data.set_words(words, length); - } +BigInt::BigInt(const word words[], size_t length) { m_data.set_words(words, length); } /* -* Construct a BigInt from a regular number -*/ -BigInt::BigInt(uint64_t n) - { - if(n > 0) - { + * Construct a BigInt from a regular number + */ +BigInt::BigInt(uint64_t n) { + if (n > 0) { #if BOTAN_MP_WORD_BITS == 32 - m_data.set_word_at(0, static_cast(n)); - m_data.set_word_at(1, static_cast(n >> 32)); + m_data.set_word_at(0, static_cast(n)); + m_data.set_word_at(1, static_cast(n >> 32)); #else - m_data.set_word_at(0, n); + m_data.set_word_at(0, n); #endif - } - - } + } +} /* -* Construct a BigInt of the specified size -*/ -BigInt::BigInt(Sign s, size_t size) - { - m_data.set_size(size); - m_signedness = s; - } + * Construct a BigInt of the specified size + */ +BigInt::BigInt(Sign s, size_t size) { + m_data.set_size(size); + m_signedness = s; +} /* -* Construct a BigInt from a string -*/ -BigInt::BigInt(const std::string& str) - { - Base base = Decimal; - size_t markers = 0; - bool negative = false; + * Construct a BigInt from a string + */ +BigInt::BigInt(const std::string& str) { + Base base = Decimal; + size_t markers = 0; + bool negative = false; - if(str.length() > 0 && str[0] == '-') - { - markers += 1; - negative = true; - } + if (str.length() > 0 && str[0] == '-') { + markers += 1; + negative = true; + } - if(str.length() > markers + 2 && str[markers ] == '0' && - str[markers + 1] == 'x') - { - markers += 2; - base = Hexadecimal; - } + if (str.length() > markers + 2 && str[markers] == '0' && str[markers + 1] == 'x') { + markers += 2; + base = Hexadecimal; + } - *this = decode(cast_char_ptr_to_uint8(str.data()) + markers, - str.length() - markers, base); + *this = decode(cast_char_ptr_to_uint8(str.data()) + markers, str.length() - markers, base); - if(negative) set_sign(Negative); - else set_sign(Positive); - } + if (negative) + set_sign(Negative); + else + set_sign(Positive); +} -BigInt::BigInt(const uint8_t input[], size_t length) - { - binary_decode(input, length); - } +BigInt::BigInt(const uint8_t input[], size_t length) { binary_decode(input, length); } /* -* Construct a BigInt from an encoded BigInt -*/ -BigInt::BigInt(const uint8_t input[], size_t length, Base base) - { - *this = decode(input, length, base); - } + * Construct a BigInt from an encoded BigInt + */ +BigInt::BigInt(const uint8_t input[], size_t length, Base base) { + *this = decode(input, length, base); +} -BigInt::BigInt(const uint8_t buf[], size_t length, size_t max_bits) - { - const size_t max_bytes = std::min(length, (max_bits + 7) / 8); - binary_decode(buf, max_bytes); +BigInt::BigInt(const uint8_t buf[], size_t length, size_t max_bits) { + const size_t max_bytes = std::min(length, (max_bits + 7) / 8); + binary_decode(buf, max_bytes); - const size_t b = this->bits(); - if(b > max_bits) - { - *this >>= (b - max_bits); - } - } + const size_t b = this->bits(); + if (b > max_bits) { + *this >>= (b - max_bits); + } +} /* -* Construct a BigInt from an encoded BigInt -*/ -BigInt::BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit) - { - randomize(rng, bits, set_high_bit); - } + * Construct a BigInt from an encoded BigInt + */ +BigInt::BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit) { + randomize(rng, bits, set_high_bit); +} -uint8_t BigInt::byte_at(size_t n) const - { - return get_byte(sizeof(word) - (n % sizeof(word)) - 1, - word_at(n / sizeof(word))); - } +uint8_t BigInt::byte_at(size_t n) const { + return get_byte(sizeof(word) - (n % sizeof(word)) - 1, word_at(n / sizeof(word))); +} -int32_t BigInt::cmp_word(word other) const - { - if(is_negative()) - return -1; // other is positive ... +int32_t BigInt::cmp_word(word other) const { + if (is_negative()) return -1; // other is positive ... - const size_t sw = this->sig_words(); - if(sw > 1) - return 1; // must be larger since other is just one word ... + const size_t sw = this->sig_words(); + if (sw > 1) return 1; // must be larger since other is just one word ... - return bigint_cmp(this->data(), sw, &other, 1); - } + return bigint_cmp(this->data(), sw, &other, 1); +} /* -* Comparison Function -*/ -int32_t BigInt::cmp(const BigInt& other, bool check_signs) const - { - if(check_signs) - { - if(other.is_positive() && this->is_negative()) - return -1; + * Comparison Function + */ +int32_t BigInt::cmp(const BigInt& other, bool check_signs) const { + if (check_signs) { + if (other.is_positive() && this->is_negative()) return -1; - if(other.is_negative() && this->is_positive()) - return 1; + if (other.is_negative() && this->is_positive()) return 1; - if(other.is_negative() && this->is_negative()) - return (-bigint_cmp(this->data(), this->size(), - other.data(), other.size())); - } + if (other.is_negative() && this->is_negative()) + return (-bigint_cmp(this->data(), this->size(), other.data(), other.size())); + } - return bigint_cmp(this->data(), this->size(), - other.data(), other.size()); - } + return bigint_cmp(this->data(), this->size(), other.data(), other.size()); +} -bool BigInt::is_equal(const BigInt& other) const - { - if(this->sign() != other.sign()) - return false; +bool BigInt::is_equal(const BigInt& other) const { + if (this->sign() != other.sign()) return false; - return bigint_ct_is_eq(this->data(), this->sig_words(), - other.data(), other.sig_words()).is_set(); - } + return bigint_ct_is_eq(this->data(), this->sig_words(), other.data(), other.sig_words()) + .is_set(); +} -bool BigInt::is_less_than(const BigInt& other) const - { - if(this->is_negative() && other.is_positive()) - return true; +bool BigInt::is_less_than(const BigInt& other) const { + if (this->is_negative() && other.is_positive()) return true; - if(this->is_positive() && other.is_negative()) - return false; + if (this->is_positive() && other.is_negative()) return false; - if(other.is_negative() && this->is_negative()) - { - return !bigint_ct_is_lt(other.data(), other.sig_words(), - this->data(), this->sig_words(), true).is_set(); - } + if (other.is_negative() && this->is_negative()) { + return !bigint_ct_is_lt(other.data(), other.sig_words(), this->data(), this->sig_words(), + true) + .is_set(); + } - return bigint_ct_is_lt(this->data(), this->sig_words(), - other.data(), other.sig_words()).is_set(); - } + return bigint_ct_is_lt(this->data(), this->sig_words(), other.data(), other.sig_words()) + .is_set(); +} -void BigInt::encode_words(word out[], size_t size) const - { - const size_t words = sig_words(); +void BigInt::encode_words(word out[], size_t size) const { + const size_t words = sig_words(); - if(words > size) - throw Encoding_Error("BigInt::encode_words value too large to encode"); + if (words > size) throw Encoding_Error("BigInt::encode_words value too large to encode"); - clear_mem(out, size); - copy_mem(out, data(), words); - } + clear_mem(out, size); + copy_mem(out, data(), words); +} -size_t BigInt::Data::calc_sig_words() const - { - const size_t sz = m_reg.size(); - size_t sig = sz; +size_t BigInt::Data::calc_sig_words() const { + const size_t sz = m_reg.size(); + size_t sig = sz; - word sub = 1; + word sub = 1; - for(size_t i = 0; i != sz; ++i) - { - const word w = m_reg[sz - i - 1]; - sub &= ct_is_zero(w); - sig -= sub; - } + for (size_t i = 0; i != sz; ++i) { + const word w = m_reg[sz - i - 1]; + sub &= ct_is_zero(w); + sig -= sub; + } - /* - * This depends on the data so is poisoned, but unpoison it here as - * later conditionals are made on the size. - */ - CT::unpoison(sig); + /* + * This depends on the data so is poisoned, but unpoison it here as + * later conditionals are made on the size. + */ + CT::unpoison(sig); - return sig; - } + return sig; +} /* -* Return bits {offset...offset+length} -*/ -uint32_t BigInt::get_substring(size_t offset, size_t length) const - { - if(length == 0 || length > 32) - throw Invalid_Argument("BigInt::get_substring invalid substring length"); + * Return bits {offset...offset+length} + */ +uint32_t BigInt::get_substring(size_t offset, size_t length) const { + if (length == 0 || length > 32) + throw Invalid_Argument("BigInt::get_substring invalid substring length"); - const size_t byte_offset = offset / 8; - const size_t shift = (offset % 8); - const uint32_t mask = 0xFFFFFFFF >> (32 - length); + const size_t byte_offset = offset / 8; + const size_t shift = (offset % 8); + const uint32_t mask = 0xFFFFFFFF >> (32 - length); - const uint8_t b0 = byte_at(byte_offset); - const uint8_t b1 = byte_at(byte_offset + 1); - const uint8_t b2 = byte_at(byte_offset + 2); - const uint8_t b3 = byte_at(byte_offset + 3); - const uint8_t b4 = byte_at(byte_offset + 4); - const uint64_t piece = make_uint64(0, 0, 0, b4, b3, b2, b1, b0); + const uint8_t b0 = byte_at(byte_offset); + const uint8_t b1 = byte_at(byte_offset + 1); + const uint8_t b2 = byte_at(byte_offset + 2); + const uint8_t b3 = byte_at(byte_offset + 3); + const uint8_t b4 = byte_at(byte_offset + 4); + const uint64_t piece = make_uint64(0, 0, 0, b4, b3, b2, b1, b0); - return static_cast((piece >> shift) & mask); - } + return static_cast((piece >> shift) & mask); +} /* -* Convert this number to a uint32_t, if possible -*/ -uint32_t BigInt::to_u32bit() const - { - if(is_negative()) - throw Encoding_Error("BigInt::to_u32bit: Number is negative"); - if(bits() > 32) - throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert"); + * Convert this number to a uint32_t, if possible + */ +uint32_t BigInt::to_u32bit() const { + if (is_negative()) throw Encoding_Error("BigInt::to_u32bit: Number is negative"); + if (bits() > 32) throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert"); - uint32_t out = 0; - for(size_t i = 0; i != 4; ++i) - out = (out << 8) | byte_at(3-i); - return out; - } + uint32_t out = 0; + for (size_t i = 0; i != 4; ++i) out = (out << 8) | byte_at(3 - i); + return out; +} /* -* Set bit number n -*/ -void BigInt::conditionally_set_bit(size_t n, bool set_it) - { - const size_t which = n / BOTAN_MP_WORD_BITS; - const word mask = static_cast(set_it) << (n % BOTAN_MP_WORD_BITS); - m_data.set_word_at(which, word_at(which) | mask); - } + * Set bit number n + */ +void BigInt::conditionally_set_bit(size_t n, bool set_it) { + const size_t which = n / BOTAN_MP_WORD_BITS; + const word mask = static_cast(set_it) << (n % BOTAN_MP_WORD_BITS); + m_data.set_word_at(which, word_at(which) | mask); +} /* -* Clear bit number n -*/ -void BigInt::clear_bit(size_t n) - { - const size_t which = n / BOTAN_MP_WORD_BITS; + * Clear bit number n + */ +void BigInt::clear_bit(size_t n) { + const size_t which = n / BOTAN_MP_WORD_BITS; - if(which < size()) - { - const word mask = ~(static_cast(1) << (n % BOTAN_MP_WORD_BITS)); - m_data.set_word_at(which, word_at(which) & mask); - } - } + if (which < size()) { + const word mask = ~(static_cast(1) << (n % BOTAN_MP_WORD_BITS)); + m_data.set_word_at(which, word_at(which) & mask); + } +} -size_t BigInt::bytes() const - { - return round_up(bits(), 8) / 8; - } +size_t BigInt::bytes() const { return round_up(bits(), 8) / 8; } -size_t BigInt::top_bits_free() const - { - const size_t words = sig_words(); +size_t BigInt::top_bits_free() const { + const size_t words = sig_words(); - const word top_word = word_at(words - 1); - const size_t bits_used = high_bit(top_word); - CT::unpoison(bits_used); - return BOTAN_MP_WORD_BITS - bits_used; - } + const word top_word = word_at(words - 1); + const size_t bits_used = high_bit(top_word); + CT::unpoison(bits_used); + return BOTAN_MP_WORD_BITS - bits_used; +} -size_t BigInt::bits() const - { - const size_t words = sig_words(); +size_t BigInt::bits() const { + const size_t words = sig_words(); - if(words == 0) - return 0; + if (words == 0) return 0; - const size_t full_words = (words - 1) * BOTAN_MP_WORD_BITS; - const size_t top_bits = BOTAN_MP_WORD_BITS - top_bits_free(); + const size_t full_words = (words - 1) * BOTAN_MP_WORD_BITS; + const size_t top_bits = BOTAN_MP_WORD_BITS - top_bits_free(); - return full_words + top_bits; - } + return full_words + top_bits; +} /* -* Calcluate the size in a certain base -*/ -size_t BigInt::encoded_size(Base base) const - { - static const double LOG_2_BASE_10 = 0.30102999566; + * Calcluate the size in a certain base + */ +size_t BigInt::encoded_size(Base base) const { + static const double LOG_2_BASE_10 = 0.30102999566; - if(base == Binary) - return bytes(); - else if(base == Hexadecimal) - return 2*bytes(); - else if(base == Decimal) - return static_cast((bits() * LOG_2_BASE_10) + 1); - else - throw Invalid_Argument("Unknown base for BigInt encoding"); - } + if (base == Binary) + return bytes(); + else if (base == Hexadecimal) + return 2 * bytes(); + else if (base == Decimal) + return static_cast((bits() * LOG_2_BASE_10) + 1); + else + throw Invalid_Argument("Unknown base for BigInt encoding"); +} /* -* Return the negation of this number -*/ -BigInt BigInt::operator-() const - { - BigInt x = (*this); - x.flip_sign(); - return x; - } + * Return the negation of this number + */ +BigInt BigInt::operator-() const { + BigInt x = (*this); + x.flip_sign(); + return x; +} -size_t BigInt::reduce_below(const BigInt& p, secure_vector& ws) - { - if(p.is_negative() || this->is_negative()) - throw Invalid_Argument("BigInt::reduce_below both values must be positive"); +size_t BigInt::reduce_below(const BigInt& p, secure_vector& ws) { + if (p.is_negative() || this->is_negative()) + throw Invalid_Argument("BigInt::reduce_below both values must be positive"); - const size_t p_words = p.sig_words(); + const size_t p_words = p.sig_words(); - if(size() < p_words + 1) - grow_to(p_words + 1); + if (size() < p_words + 1) grow_to(p_words + 1); - if(ws.size() < p_words + 1) - ws.resize(p_words + 1); + if (ws.size() < p_words + 1) ws.resize(p_words + 1); - clear_mem(ws.data(), ws.size()); + clear_mem(ws.data(), ws.size()); - size_t reductions = 0; + size_t reductions = 0; - for(;;) - { - word borrow = bigint_sub3(ws.data(), data(), p_words + 1, p.data(), p_words); - if(borrow) - break; + for (;;) { + word borrow = bigint_sub3(ws.data(), data(), p_words + 1, p.data(), p_words); + if (borrow) break; - ++reductions; - swap_reg(ws); - } + ++reductions; + swap_reg(ws); + } - return reductions; - } + return reductions; +} -void BigInt::ct_reduce_below(const BigInt& mod, secure_vector& ws, size_t bound) - { - if(mod.is_negative() || this->is_negative()) - throw Invalid_Argument("BigInt::ct_reduce_below both values must be positive"); +void BigInt::ct_reduce_below(const BigInt& mod, secure_vector& ws, size_t bound) { + if (mod.is_negative() || this->is_negative()) + throw Invalid_Argument("BigInt::ct_reduce_below both values must be positive"); - const size_t mod_words = mod.sig_words(); + const size_t mod_words = mod.sig_words(); - grow_to(mod_words); + grow_to(mod_words); - const size_t sz = size(); + const size_t sz = size(); - ws.resize(sz); + ws.resize(sz); - clear_mem(ws.data(), sz); + clear_mem(ws.data(), sz); - for(size_t i = 0; i != bound; ++i) - { - word borrow = bigint_sub3(ws.data(), data(), sz, mod.data(), mod_words); + for (size_t i = 0; i != bound; ++i) { + word borrow = bigint_sub3(ws.data(), data(), sz, mod.data(), mod_words); - CT::Mask::is_zero(borrow).select_n(mutable_data(), ws.data(), data(), sz); - } - } + CT::Mask::is_zero(borrow).select_n(mutable_data(), ws.data(), data(), sz); + } +} /* -* Return the absolute value of this number -*/ -BigInt BigInt::abs() const - { - BigInt x = (*this); - x.set_sign(Positive); - return x; - } + * Return the absolute value of this number + */ +BigInt BigInt::abs() const { + BigInt x = (*this); + x.set_sign(Positive); + return x; +} -void BigInt::binary_encode(uint8_t buf[]) const - { - this->binary_encode(buf, bytes()); - } +void BigInt::binary_encode(uint8_t buf[]) const { this->binary_encode(buf, bytes()); } /* -* Encode this number into bytes -*/ -void BigInt::binary_encode(uint8_t output[], size_t len) const - { - const size_t full_words = len / sizeof(word); - const size_t extra_bytes = len % sizeof(word); + * Encode this number into bytes + */ +void BigInt::binary_encode(uint8_t output[], size_t len) const { + const size_t full_words = len / sizeof(word); + const size_t extra_bytes = len % sizeof(word); - for(size_t i = 0; i != full_words; ++i) - { - const word w = word_at(i); - store_be(w, output + (len - (i+1)*sizeof(word))); - } + for (size_t i = 0; i != full_words; ++i) { + const word w = word_at(i); + store_be(w, output + (len - (i + 1) * sizeof(word))); + } - if(extra_bytes > 0) - { - const word w = word_at(full_words); + if (extra_bytes > 0) { + const word w = word_at(full_words); - for(size_t i = 0; i != extra_bytes; ++i) - { - output[extra_bytes - i - 1] = get_byte(sizeof(word) - i - 1, w); - } - } - } + for (size_t i = 0; i != extra_bytes; ++i) { + output[extra_bytes - i - 1] = get_byte(sizeof(word) - i - 1, w); + } + } +} /* -* Set this number to the value in buf -*/ -void BigInt::binary_decode(const uint8_t buf[], size_t length) - { - clear(); + * Set this number to the value in buf + */ +void BigInt::binary_decode(const uint8_t buf[], size_t length) { + clear(); - const size_t full_words = length / sizeof(word); - const size_t extra_bytes = length % sizeof(word); + const size_t full_words = length / sizeof(word); + const size_t extra_bytes = length % sizeof(word); - secure_vector reg((round_up(full_words + (extra_bytes > 0 ? 1 : 0), 8))); + secure_vector reg((round_up(full_words + (extra_bytes > 0 ? 1 : 0), 8))); - for(size_t i = 0; i != full_words; ++i) - { - reg[i] = load_be(buf + length - sizeof(word)*(i+1), 0); - } + for (size_t i = 0; i != full_words; ++i) { + reg[i] = load_be(buf + length - sizeof(word) * (i + 1), 0); + } - if(extra_bytes > 0) - { - for(size_t i = 0; i != extra_bytes; ++i) - reg[full_words] = (reg[full_words] << 8) | buf[i]; - } + if (extra_bytes > 0) { + for (size_t i = 0; i != extra_bytes; ++i) reg[full_words] = (reg[full_words] << 8) | buf[i]; + } - m_data.swap(reg); - } + m_data.swap(reg); +} -void BigInt::ct_cond_swap(bool predicate, BigInt& other) - { - const size_t max_words = std::max(size(), other.size()); - grow_to(max_words); - other.grow_to(max_words); +void BigInt::ct_cond_swap(bool predicate, BigInt& other) { + const size_t max_words = std::max(size(), other.size()); + grow_to(max_words); + other.grow_to(max_words); - bigint_cnd_swap(predicate, this->mutable_data(), other.mutable_data(), max_words); - } + bigint_cnd_swap(predicate, this->mutable_data(), other.mutable_data(), max_words); +} -void BigInt::cond_flip_sign(bool predicate) - { - // This code is assuming Negative == 0, Positive == 1 +void BigInt::cond_flip_sign(bool predicate) { + // This code is assuming Negative == 0, Positive == 1 - const auto mask = CT::Mask::expand(predicate); + const auto mask = CT::Mask::expand(predicate); - const uint8_t current_sign = static_cast(sign()); + const uint8_t current_sign = static_cast(sign()); - const uint8_t new_sign = mask.select(current_sign ^ 1, current_sign); + const uint8_t new_sign = mask.select(current_sign ^ 1, current_sign); - set_sign(static_cast(new_sign)); - } + set_sign(static_cast(new_sign)); +} -void BigInt::ct_cond_assign(bool predicate, const BigInt& other) - { - const size_t t_words = size(); - const size_t o_words = other.size(); +void BigInt::ct_cond_assign(bool predicate, const BigInt& other) { + const size_t t_words = size(); + const size_t o_words = other.size(); - if(o_words < t_words) - grow_to(o_words); + if (o_words < t_words) grow_to(o_words); - const size_t r_words = std::max(t_words, o_words); + const size_t r_words = std::max(t_words, o_words); - const auto mask = CT::Mask::expand(predicate); + const auto mask = CT::Mask::expand(predicate); - for(size_t i = 0; i != r_words; ++i) - { - const word o_word = other.word_at(i); - const word t_word = this->word_at(i); - this->set_word_at(i, mask.select(o_word, t_word)); - } + for (size_t i = 0; i != r_words; ++i) { + const word o_word = other.word_at(i); + const word t_word = this->word_at(i); + this->set_word_at(i, mask.select(o_word, t_word)); + } - if(sign() != other.sign()) - { - cond_flip_sign(predicate); - } - } + if (sign() != other.sign()) { + cond_flip_sign(predicate); + } +} #if defined(BOTAN_HAS_VALGRIND) -void BigInt::const_time_poison() const - { - CT::poison(m_data.const_data(), m_data.size()); - } +void BigInt::const_time_poison() const { CT::poison(m_data.const_data(), m_data.size()); } -void BigInt::const_time_unpoison() const - { - CT::unpoison(m_data.const_data(), m_data.size()); - } +void BigInt::const_time_unpoison() const { CT::unpoison(m_data.const_data(), m_data.size()); } #endif -void BigInt::const_time_lookup(secure_vector& output, - const std::vector& vec, - size_t idx) - { - const size_t words = output.size(); +void BigInt::const_time_lookup(secure_vector& output, const std::vector& vec, + size_t idx) { + const size_t words = output.size(); - clear_mem(output.data(), output.size()); + clear_mem(output.data(), output.size()); - CT::poison(&idx, sizeof(idx)); + CT::poison(&idx, sizeof(idx)); - for(size_t i = 0; i != vec.size(); ++i) - { - BOTAN_ASSERT(vec[i].size() >= words, - "Word size as expected in const_time_lookup"); + for (size_t i = 0; i != vec.size(); ++i) { + BOTAN_ASSERT(vec[i].size() >= words, "Word size as expected in const_time_lookup"); - const auto mask = CT::Mask::is_equal(i, idx); + const auto mask = CT::Mask::is_equal(i, idx); - for(size_t w = 0; w != words; ++w) - { - const word viw = vec[i].word_at(w); - output[w] = mask.if_set_return(viw); - } - } - - CT::unpoison(idx); - CT::unpoison(output.data(), output.size()); - } + for (size_t w = 0; w != words; ++w) { + const word viw = vec[i].word_at(w); + output[w] = mask.if_set_return(viw); + } + } + CT::unpoison(idx); + CT::unpoison(output.data(), output.size()); } -/* -* Division Algorithm -* (C) 1999-2007,2012,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * Division Algorithm + * (C) 1999-2007,2012,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { /* -* Handle signed operands, if necessary -*/ -void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r) - { - q.cond_flip_sign(x.sign() != y.sign()); - - if(x.is_negative() && r.is_nonzero()) - { - q -= 1; - r = y.abs() - r; - } - } - -inline bool division_check(word q, word y2, word y1, - word x3, word x2, word x1) - { - /* - Compute (y3,y2,y1) = (y2,y1) * q - and return true if (y3,y2,y1) > (x3,x2,x1) - */ - - word y3 = 0; - y1 = word_madd2(q, y1, &y3); - y2 = word_madd2(q, y2, &y3); - - const word x[3] = { x1, x2, x3 }; - const word y[3] = { y1, y2, y3 }; - - return bigint_ct_is_lt(x, 3, y, 3).is_set(); - } + * Handle signed operands, if necessary + */ +void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r) { + q.cond_flip_sign(x.sign() != y.sign()); + if (x.is_negative() && r.is_nonzero()) { + q -= 1; + r = y.abs() - r; + } } -void ct_divide(const BigInt& x, const BigInt& y, BigInt& q_out, BigInt& r_out) - { - const size_t x_words = x.sig_words(); - const size_t y_words = y.sig_words(); +inline bool division_check(word q, word y2, word y1, word x3, word x2, word x1) { + /* + Compute (y3,y2,y1) = (y2,y1) * q + and return true if (y3,y2,y1) > (x3,x2,x1) + */ - const size_t x_bits = x.bits(); + word y3 = 0; + y1 = word_madd2(q, y1, &y3); + y2 = word_madd2(q, y2, &y3); - BigInt q(BigInt::Positive, x_words); - BigInt r(BigInt::Positive, y_words); - BigInt t(BigInt::Positive, y_words); // a temporary - - for(size_t i = 0; i != x_bits; ++i) - { - const size_t b = x_bits - 1 - i; - const bool x_b = x.get_bit(b); - - r *= 2; - r.conditionally_set_bit(0, x_b); - - const bool r_gte_y = bigint_sub3(t.mutable_data(), r.data(), r.size(), y.data(), y_words) == 0; - - q.conditionally_set_bit(b, r_gte_y); - r.ct_cond_swap(r_gte_y, t); - } - - sign_fixup(x, y, q, r); - r_out = r; - q_out = q; - } - -void ct_divide_u8(const BigInt& x, uint8_t y, BigInt& q_out, uint8_t& r_out) - { - const size_t x_words = x.sig_words(); - const size_t x_bits = x.bits(); - - BigInt q(BigInt::Positive, x_words); - uint32_t r = 0; - - for(size_t i = 0; i != x_bits; ++i) - { - const size_t b = x_bits - 1 - i; - const bool x_b = x.get_bit(b); - - r *= 2; - r += x_b; - - const auto r_gte_y = CT::Mask::is_gte(r, y); - - q.conditionally_set_bit(b, r_gte_y.is_set()); - r = r_gte_y.select(r - y, r); - } - - if(x.is_negative()) - { - q.flip_sign(); - if(r != 0) - { - --q; - r = y - r; - } - } - - r_out = static_cast(r); - q_out = q; - } - -BigInt ct_modulo(const BigInt& x, const BigInt& y) - { - if(y.is_negative() || y.is_zero()) - throw Invalid_Argument("ct_modulo requires y > 0"); - - const size_t y_words = y.sig_words(); - - const size_t x_bits = x.bits(); - - BigInt r(BigInt::Positive, y_words); - BigInt t(BigInt::Positive, y_words); - - for(size_t i = 0; i != x_bits; ++i) - { - const size_t b = x_bits - 1 - i; - const bool x_b = x.get_bit(b); - - r *= 2; - r.conditionally_set_bit(0, x_b); - - const bool r_gte_y = bigint_sub3(t.mutable_data(), r.data(), r.size(), y.data(), y_words) == 0; - - r.ct_cond_swap(r_gte_y, t); - } - - if(x.is_negative()) - { - if(r.is_nonzero()) - { - r = y - r; - } - } - - return r; - } - -/* -* Solve x = q * y + r -* -* See Handbook of Applied Cryptography section 14.2.5 -*/ -void divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& r_out) - { - if(y_arg.is_zero()) - throw BigInt::DivideByZero(); - - const size_t y_words = y_arg.sig_words(); - - BOTAN_ASSERT_NOMSG(y_words > 0); - - BigInt y = y_arg; - - BigInt r = x; - BigInt q = 0; - secure_vector ws; - - r.set_sign(BigInt::Positive); - y.set_sign(BigInt::Positive); - - // Calculate shifts needed to normalize y with high bit set - const size_t shifts = y.top_bits_free(); - - y <<= shifts; - r <<= shifts; - - // we know y has not changed size, since we only shifted up to set high bit - const size_t t = y_words - 1; - const size_t n = std::max(y_words, r.sig_words()) - 1; // r may have changed size however - - BOTAN_ASSERT_NOMSG(n >= t); - - q.grow_to(n - t + 1); - - word* q_words = q.mutable_data(); - - BigInt shifted_y = y << (BOTAN_MP_WORD_BITS * (n-t)); - - // Set q_{n-t} to number of times r > shifted_y - q_words[n-t] = r.reduce_below(shifted_y, ws); - - const word y_t0 = y.word_at(t); - const word y_t1 = y.word_at(t-1); - BOTAN_DEBUG_ASSERT((y_t0 >> (BOTAN_MP_WORD_BITS-1)) == 1); - - for(size_t j = n; j != t; --j) - { - const word x_j0 = r.word_at(j); - const word x_j1 = r.word_at(j-1); - const word x_j2 = r.word_at(j-2); - - word qjt = bigint_divop(x_j0, x_j1, y_t0); - - qjt = CT::Mask::is_equal(x_j0, y_t0).select(MP_WORD_MAX, qjt); - - // Per HAC 14.23, this operation is required at most twice - qjt -= division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2); - qjt -= division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2); - BOTAN_DEBUG_ASSERT(division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2) == false); - - shifted_y >>= BOTAN_MP_WORD_BITS; - // Now shifted_y == y << (BOTAN_MP_WORD_BITS * (j-t-1)) - - // TODO this sequence could be better - r -= qjt * shifted_y; - qjt -= r.is_negative(); - r += static_cast(r.is_negative()) * shifted_y; - - q_words[j-t-1] = qjt; - } - - r >>= shifts; - - sign_fixup(x, y_arg, q, r); - - r_out = r; - q_out = q; - } + const word x[3] = {x1, x2, x3}; + const word y[3] = {y1, y2, y3}; + return bigint_ct_is_lt(x, 3, y, 3).is_set(); } -/* -* Block Ciphers -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace + +void ct_divide(const BigInt& x, const BigInt& y, BigInt& q_out, BigInt& r_out) { + const size_t x_words = x.sig_words(); + const size_t y_words = y.sig_words(); + + const size_t x_bits = x.bits(); + + BigInt q(BigInt::Positive, x_words); + BigInt r(BigInt::Positive, y_words); + BigInt t(BigInt::Positive, y_words); // a temporary + + for (size_t i = 0; i != x_bits; ++i) { + const size_t b = x_bits - 1 - i; + const bool x_b = x.get_bit(b); + + r *= 2; + r.conditionally_set_bit(0, x_b); + + const bool r_gte_y = + bigint_sub3(t.mutable_data(), r.data(), r.size(), y.data(), y_words) == 0; + + q.conditionally_set_bit(b, r_gte_y); + r.ct_cond_swap(r_gte_y, t); + } + + sign_fixup(x, y, q, r); + r_out = r; + q_out = q; +} + +void ct_divide_u8(const BigInt& x, uint8_t y, BigInt& q_out, uint8_t& r_out) { + const size_t x_words = x.sig_words(); + const size_t x_bits = x.bits(); + + BigInt q(BigInt::Positive, x_words); + uint32_t r = 0; + + for (size_t i = 0; i != x_bits; ++i) { + const size_t b = x_bits - 1 - i; + const bool x_b = x.get_bit(b); + + r *= 2; + r += x_b; + + const auto r_gte_y = CT::Mask::is_gte(r, y); + + q.conditionally_set_bit(b, r_gte_y.is_set()); + r = r_gte_y.select(r - y, r); + } + + if (x.is_negative()) { + q.flip_sign(); + if (r != 0) { + --q; + r = y - r; + } + } + + r_out = static_cast(r); + q_out = q; +} + +BigInt ct_modulo(const BigInt& x, const BigInt& y) { + if (y.is_negative() || y.is_zero()) throw Invalid_Argument("ct_modulo requires y > 0"); + + const size_t y_words = y.sig_words(); + + const size_t x_bits = x.bits(); + + BigInt r(BigInt::Positive, y_words); + BigInt t(BigInt::Positive, y_words); + + for (size_t i = 0; i != x_bits; ++i) { + const size_t b = x_bits - 1 - i; + const bool x_b = x.get_bit(b); + + r *= 2; + r.conditionally_set_bit(0, x_b); + + const bool r_gte_y = + bigint_sub3(t.mutable_data(), r.data(), r.size(), y.data(), y_words) == 0; + + r.ct_cond_swap(r_gte_y, t); + } + + if (x.is_negative()) { + if (r.is_nonzero()) { + r = y - r; + } + } + + return r; +} + +/* + * Solve x = q * y + r + * + * See Handbook of Applied Cryptography section 14.2.5 + */ +void divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& r_out) { + if (y_arg.is_zero()) throw BigInt::DivideByZero(); + + const size_t y_words = y_arg.sig_words(); + + BOTAN_ASSERT_NOMSG(y_words > 0); + + BigInt y = y_arg; + + BigInt r = x; + BigInt q = 0; + secure_vector ws; + + r.set_sign(BigInt::Positive); + y.set_sign(BigInt::Positive); + + // Calculate shifts needed to normalize y with high bit set + const size_t shifts = y.top_bits_free(); + + y <<= shifts; + r <<= shifts; + + // we know y has not changed size, since we only shifted up to set high bit + const size_t t = y_words - 1; + const size_t n = std::max(y_words, r.sig_words()) - 1; // r may have changed size however + + BOTAN_ASSERT_NOMSG(n >= t); + + q.grow_to(n - t + 1); + + word* q_words = q.mutable_data(); + + BigInt shifted_y = y << (BOTAN_MP_WORD_BITS * (n - t)); + + // Set q_{n-t} to number of times r > shifted_y + q_words[n - t] = r.reduce_below(shifted_y, ws); + + const word y_t0 = y.word_at(t); + const word y_t1 = y.word_at(t - 1); + BOTAN_DEBUG_ASSERT((y_t0 >> (BOTAN_MP_WORD_BITS - 1)) == 1); + + for (size_t j = n; j != t; --j) { + const word x_j0 = r.word_at(j); + const word x_j1 = r.word_at(j - 1); + const word x_j2 = r.word_at(j - 2); + + word qjt = bigint_divop(x_j0, x_j1, y_t0); + + qjt = CT::Mask::is_equal(x_j0, y_t0).select(MP_WORD_MAX, qjt); + + // Per HAC 14.23, this operation is required at most twice + qjt -= division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2); + qjt -= division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2); + BOTAN_DEBUG_ASSERT(division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2) == false); + + shifted_y >>= BOTAN_MP_WORD_BITS; + // Now shifted_y == y << (BOTAN_MP_WORD_BITS * (j-t-1)) + + // TODO this sequence could be better + r -= qjt * shifted_y; + qjt -= r.is_negative(); + r += static_cast(r.is_negative()) * shifted_y; + + q_words[j - t - 1] = qjt; + } + + r >>= shifts; + + sign_fixup(x, y_arg, q, r); + + r_out = r; + q_out = q; +} + +} // namespace Botan +/* + * Block Ciphers + * (C) 2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_AES) #endif @@ -6018,1026 +5044,842 @@ void divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& r_out) namespace Botan { -std::unique_ptr -BlockCipher::create(const std::string& algo, - const std::string& provider) - { +std::unique_ptr BlockCipher::create(const std::string& algo, + const std::string& provider) { #if defined(BOTAN_HAS_COMMONCRYPTO) - if(provider.empty() || provider == "commoncrypto") - { - if(auto bc = make_commoncrypto_block_cipher(algo)) - return bc; + if (provider.empty() || provider == "commoncrypto") { + if (auto bc = make_commoncrypto_block_cipher(algo)) return bc; - if(!provider.empty()) - return nullptr; - } + if (!provider.empty()) return nullptr; + } #endif #if defined(BOTAN_HAS_OPENSSL) - if(provider.empty() || provider == "openssl") - { - if(auto bc = make_openssl_block_cipher(algo)) - return bc; + if (provider.empty() || provider == "openssl") { + if (auto bc = make_openssl_block_cipher(algo)) return bc; - if(!provider.empty()) - return nullptr; - } + if (!provider.empty()) return nullptr; + } #endif - // TODO: CryptoAPI - // TODO: /dev/crypto + // TODO: CryptoAPI + // TODO: /dev/crypto - // Only base providers from here on out - if(provider.empty() == false && provider != "base") - return nullptr; + // Only base providers from here on out + if (provider.empty() == false && provider != "base") return nullptr; #if defined(BOTAN_HAS_AES) - if(algo == "AES-128") - { - return std::unique_ptr(new AES_128); - } + if (algo == "AES-128") { + return std::unique_ptr(new AES_128); + } - if(algo == "AES-192") - { - return std::unique_ptr(new AES_192); - } + if (algo == "AES-192") { + return std::unique_ptr(new AES_192); + } - if(algo == "AES-256") - { - return std::unique_ptr(new AES_256); - } + if (algo == "AES-256") { + return std::unique_ptr(new AES_256); + } #endif #if defined(BOTAN_HAS_ARIA) - if(algo == "ARIA-128") - { - return std::unique_ptr(new ARIA_128); - } + if (algo == "ARIA-128") { + return std::unique_ptr(new ARIA_128); + } - if(algo == "ARIA-192") - { - return std::unique_ptr(new ARIA_192); - } + if (algo == "ARIA-192") { + return std::unique_ptr(new ARIA_192); + } - if(algo == "ARIA-256") - { - return std::unique_ptr(new ARIA_256); - } + if (algo == "ARIA-256") { + return std::unique_ptr(new ARIA_256); + } #endif #if defined(BOTAN_HAS_SERPENT) - if(algo == "Serpent") - { - return std::unique_ptr(new Serpent); - } + if (algo == "Serpent") { + return std::unique_ptr(new Serpent); + } #endif #if defined(BOTAN_HAS_SHACAL2) - if(algo == "SHACAL2") - { - return std::unique_ptr(new SHACAL2); - } + if (algo == "SHACAL2") { + return std::unique_ptr(new SHACAL2); + } #endif #if defined(BOTAN_HAS_TWOFISH) - if(algo == "Twofish") - { - return std::unique_ptr(new Twofish); - } + if (algo == "Twofish") { + return std::unique_ptr(new Twofish); + } #endif #if defined(BOTAN_HAS_THREEFISH_512) - if(algo == "Threefish-512") - { - return std::unique_ptr(new Threefish_512); - } + if (algo == "Threefish-512") { + return std::unique_ptr(new Threefish_512); + } #endif #if defined(BOTAN_HAS_BLOWFISH) - if(algo == "Blowfish") - { - return std::unique_ptr(new Blowfish); - } + if (algo == "Blowfish") { + return std::unique_ptr(new Blowfish); + } #endif #if defined(BOTAN_HAS_CAMELLIA) - if(algo == "Camellia-128") - { - return std::unique_ptr(new Camellia_128); - } + if (algo == "Camellia-128") { + return std::unique_ptr(new Camellia_128); + } - if(algo == "Camellia-192") - { - return std::unique_ptr(new Camellia_192); - } + if (algo == "Camellia-192") { + return std::unique_ptr(new Camellia_192); + } - if(algo == "Camellia-256") - { - return std::unique_ptr(new Camellia_256); - } + if (algo == "Camellia-256") { + return std::unique_ptr(new Camellia_256); + } #endif #if defined(BOTAN_HAS_DES) - if(algo == "DES") - { - return std::unique_ptr(new DES); - } + if (algo == "DES") { + return std::unique_ptr(new DES); + } - if(algo == "DESX") - { - return std::unique_ptr(new DESX); - } + if (algo == "DESX") { + return std::unique_ptr(new DESX); + } - if(algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE") - { - return std::unique_ptr(new TripleDES); - } + if (algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE") { + return std::unique_ptr(new TripleDES); + } #endif #if defined(BOTAN_HAS_NOEKEON) - if(algo == "Noekeon") - { - return std::unique_ptr(new Noekeon); - } + if (algo == "Noekeon") { + return std::unique_ptr(new Noekeon); + } #endif #if defined(BOTAN_HAS_CAST_128) - if(algo == "CAST-128" || algo == "CAST5") - { - return std::unique_ptr(new CAST_128); - } + if (algo == "CAST-128" || algo == "CAST5") { + return std::unique_ptr(new CAST_128); + } #endif #if defined(BOTAN_HAS_CAST_256) - if(algo == "CAST-256") - { - return std::unique_ptr(new CAST_256); - } + if (algo == "CAST-256") { + return std::unique_ptr(new CAST_256); + } #endif #if defined(BOTAN_HAS_IDEA) - if(algo == "IDEA") - { - return std::unique_ptr(new IDEA); - } + if (algo == "IDEA") { + return std::unique_ptr(new IDEA); + } #endif #if defined(BOTAN_HAS_KASUMI) - if(algo == "KASUMI") - { - return std::unique_ptr(new KASUMI); - } + if (algo == "KASUMI") { + return std::unique_ptr(new KASUMI); + } #endif #if defined(BOTAN_HAS_MISTY1) - if(algo == "MISTY1") - { - return std::unique_ptr(new MISTY1); - } + if (algo == "MISTY1") { + return std::unique_ptr(new MISTY1); + } #endif #if defined(BOTAN_HAS_SEED) - if(algo == "SEED") - { - return std::unique_ptr(new SEED); - } + if (algo == "SEED") { + return std::unique_ptr(new SEED); + } #endif #if defined(BOTAN_HAS_SM4) - if(algo == "SM4") - { - return std::unique_ptr(new SM4); - } + if (algo == "SM4") { + return std::unique_ptr(new SM4); + } #endif #if defined(BOTAN_HAS_XTEA) - if(algo == "XTEA") - { - return std::unique_ptr(new XTEA); - } + if (algo == "XTEA") { + return std::unique_ptr(new XTEA); + } #endif - const SCAN_Name req(algo); + const SCAN_Name req(algo); #if defined(BOTAN_HAS_GOST_28147_89) - if(req.algo_name() == "GOST-28147-89") - { - return std::unique_ptr(new GOST_28147_89(req.arg(0, "R3411_94_TestParam"))); - } + if (req.algo_name() == "GOST-28147-89") { + return std::unique_ptr(new GOST_28147_89(req.arg(0, "R3411_94_TestParam"))); + } #endif #if defined(BOTAN_HAS_CASCADE) - if(req.algo_name() == "Cascade" && req.arg_count() == 2) - { - std::unique_ptr c1(BlockCipher::create(req.arg(0))); - std::unique_ptr c2(BlockCipher::create(req.arg(1))); + if (req.algo_name() == "Cascade" && req.arg_count() == 2) { + std::unique_ptr c1(BlockCipher::create(req.arg(0))); + std::unique_ptr c2(BlockCipher::create(req.arg(1))); - if(c1 && c2) - return std::unique_ptr(new Cascade_Cipher(c1.release(), c2.release())); - } + if (c1 && c2) + return std::unique_ptr(new Cascade_Cipher(c1.release(), c2.release())); + } #endif #if defined(BOTAN_HAS_LION) - if(req.algo_name() == "Lion" && req.arg_count_between(2, 3)) - { - std::unique_ptr hash(HashFunction::create(req.arg(0))); - std::unique_ptr stream(StreamCipher::create(req.arg(1))); + if (req.algo_name() == "Lion" && req.arg_count_between(2, 3)) { + std::unique_ptr hash(HashFunction::create(req.arg(0))); + std::unique_ptr stream(StreamCipher::create(req.arg(1))); - if(hash && stream) - { - const size_t block_size = req.arg_as_integer(2, 1024); - return std::unique_ptr(new Lion(hash.release(), stream.release(), block_size)); - } - } + if (hash && stream) { + const size_t block_size = req.arg_as_integer(2, 1024); + return std::unique_ptr( + new Lion(hash.release(), stream.release(), block_size)); + } + } #endif - BOTAN_UNUSED(req); - BOTAN_UNUSED(provider); - - return nullptr; - } - -//static -std::unique_ptr -BlockCipher::create_or_throw(const std::string& algo, - const std::string& provider) - { - if(auto bc = BlockCipher::create(algo, provider)) - { - return bc; - } - throw Lookup_Error("Block cipher", algo, provider); - } - -std::vector BlockCipher::providers(const std::string& algo) - { - return probe_providers_of(algo, { "base", "openssl", "commoncrypto" }); - } + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + return nullptr; } -/* -* CBC Mode -* (C) 1999-2007,2013,2017 Jack Lloyd -* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity -* (C) 2018 Ribose Inc -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +// static +std::unique_ptr BlockCipher::create_or_throw(const std::string& algo, + const std::string& provider) { + if (auto bc = BlockCipher::create(algo, provider)) { + return bc; + } + throw Lookup_Error("Block cipher", algo, provider); +} + +std::vector BlockCipher::providers(const std::string& algo) { + return probe_providers_of(algo, {"base", "openssl", "commoncrypto"}); +} + +} // namespace Botan +/* + * CBC Mode + * (C) 1999-2007,2013,2017 Jack Lloyd + * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity + * (C) 2018 Ribose Inc + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : - m_cipher(cipher), - m_padding(padding), - m_block_size(cipher->block_size()) - { - if(m_padding && !m_padding->valid_blocksize(m_block_size)) - throw Invalid_Argument("Padding " + m_padding->name() + - " cannot be used with " + - cipher->name() + "/CBC"); - } - -void CBC_Mode::clear() - { - m_cipher->clear(); - reset(); - } - -void CBC_Mode::reset() - { - m_state.clear(); - } - -std::string CBC_Mode::name() const - { - if(m_padding) - return cipher().name() + "/CBC/" + padding().name(); - else - return cipher().name() + "/CBC/CTS"; - } - -size_t CBC_Mode::update_granularity() const - { - return cipher().parallel_bytes(); - } - -Key_Length_Specification CBC_Mode::key_spec() const - { - return cipher().key_spec(); - } - -size_t CBC_Mode::default_nonce_length() const - { - return block_size(); - } - -bool CBC_Mode::valid_nonce_length(size_t n) const - { - return (n == 0 || n == block_size()); - } - -void CBC_Mode::key_schedule(const uint8_t key[], size_t length) - { - m_cipher->set_key(key, length); - m_state.clear(); - } - -void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) - { - if(!valid_nonce_length(nonce_len)) - throw Invalid_IV_Length(name(), nonce_len); - - /* - * A nonce of zero length means carry the last ciphertext value over - * as the new IV, as unfortunately some protocols require this. If - * this is the first message then we use an IV of all zeros. - */ - if(nonce_len) - m_state.assign(nonce, nonce + nonce_len); - else if(m_state.empty()) - m_state.resize(m_cipher->block_size()); - // else leave the state alone - } - -size_t CBC_Encryption::minimum_final_size() const - { - return 0; - } - -size_t CBC_Encryption::output_length(size_t input_length) const - { - if(input_length == 0) - return block_size(); - else - return round_up(input_length, block_size()); - } - -size_t CBC_Encryption::process(uint8_t buf[], size_t sz) - { - BOTAN_STATE_CHECK(state().empty() == false); - const size_t BS = block_size(); - - BOTAN_ASSERT(sz % BS == 0, "CBC input is full blocks"); - const size_t blocks = sz / BS; - - if(blocks > 0) - { - xor_buf(&buf[0], state_ptr(), BS); - cipher().encrypt(&buf[0]); - - for(size_t i = 1; i != blocks; ++i) - { - xor_buf(&buf[BS*i], &buf[BS*(i-1)], BS); - cipher().encrypt(&buf[BS*i]); - } - - state().assign(&buf[BS*(blocks-1)], &buf[BS*blocks]); - } - - return sz; - } - -void CBC_Encryption::finish(secure_vector& buffer, size_t offset) - { - BOTAN_STATE_CHECK(state().empty() == false); - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - - const size_t BS = block_size(); - - const size_t bytes_in_final_block = (buffer.size()-offset) % BS; - - padding().add_padding(buffer, bytes_in_final_block, BS); - - if((buffer.size()-offset) % BS) - throw Internal_Error("Did not pad to full block size in " + name()); - - update(buffer, offset); - } - -bool CTS_Encryption::valid_nonce_length(size_t n) const - { - return (n == block_size()); - } - -size_t CTS_Encryption::minimum_final_size() const - { - return block_size() + 1; - } - -size_t CTS_Encryption::output_length(size_t input_length) const - { - return input_length; // no ciphertext expansion in CTS - } - -void CTS_Encryption::finish(secure_vector& buffer, size_t offset) - { - BOTAN_STATE_CHECK(state().empty() == false); - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - uint8_t* buf = buffer.data() + offset; - const size_t sz = buffer.size() - offset; - - const size_t BS = block_size(); - - if(sz < BS + 1) - throw Encoding_Error(name() + ": insufficient data to encrypt"); - - if(sz % BS == 0) - { - update(buffer, offset); - - // swap last two blocks - for(size_t i = 0; i != BS; ++i) - std::swap(buffer[buffer.size()-BS+i], buffer[buffer.size()-2*BS+i]); - } - else - { - const size_t full_blocks = ((sz / BS) - 1) * BS; - const size_t final_bytes = sz - full_blocks; - BOTAN_ASSERT(final_bytes > BS && final_bytes < 2*BS, "Left over size in expected range"); - - secure_vector last(buf + full_blocks, buf + full_blocks + final_bytes); - buffer.resize(full_blocks + offset); - update(buffer, offset); - - xor_buf(last.data(), state_ptr(), BS); - cipher().encrypt(last.data()); - - for(size_t i = 0; i != final_bytes - BS; ++i) - { - last[i] ^= last[i + BS]; - last[i + BS] ^= last[i]; - } - - cipher().encrypt(last.data()); - - buffer += last; - } - } - -size_t CBC_Decryption::output_length(size_t input_length) const - { - return input_length; // precise for CTS, worst case otherwise - } - -size_t CBC_Decryption::minimum_final_size() const - { - return block_size(); - } - -size_t CBC_Decryption::process(uint8_t buf[], size_t sz) - { - BOTAN_STATE_CHECK(state().empty() == false); - - const size_t BS = block_size(); - - BOTAN_ASSERT(sz % BS == 0, "Input is full blocks"); - size_t blocks = sz / BS; - - while(blocks) - { - const size_t to_proc = std::min(BS * blocks, m_tempbuf.size()); - - cipher().decrypt_n(buf, m_tempbuf.data(), to_proc / BS); - - xor_buf(m_tempbuf.data(), state_ptr(), BS); - xor_buf(&m_tempbuf[BS], buf, to_proc - BS); - copy_mem(state_ptr(), buf + (to_proc - BS), BS); - - copy_mem(buf, m_tempbuf.data(), to_proc); - - buf += to_proc; - blocks -= to_proc / BS; - } - - return sz; - } - -void CBC_Decryption::finish(secure_vector& buffer, size_t offset) - { - BOTAN_STATE_CHECK(state().empty() == false); - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - const size_t sz = buffer.size() - offset; - - const size_t BS = block_size(); - - if(sz == 0 || sz % BS) - throw Decoding_Error(name() + ": Ciphertext not a multiple of block size"); - - update(buffer, offset); - - const size_t pad_bytes = BS - padding().unpad(&buffer[buffer.size()-BS], BS); - buffer.resize(buffer.size() - pad_bytes); // remove padding - if(pad_bytes == 0 && padding().name() != "NoPadding") - { - throw Decoding_Error("Invalid CBC padding"); - } - } - -void CBC_Decryption::reset() - { - CBC_Mode::reset(); - zeroise(m_tempbuf); - } - -bool CTS_Decryption::valid_nonce_length(size_t n) const - { - return (n == block_size()); - } - -size_t CTS_Decryption::minimum_final_size() const - { - return block_size() + 1; - } - -void CTS_Decryption::finish(secure_vector& buffer, size_t offset) - { - BOTAN_STATE_CHECK(state().empty() == false); - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - const size_t sz = buffer.size() - offset; - uint8_t* buf = buffer.data() + offset; - - const size_t BS = block_size(); - - if(sz < BS + 1) - throw Encoding_Error(name() + ": insufficient data to decrypt"); - - if(sz % BS == 0) - { - // swap last two blocks - - for(size_t i = 0; i != BS; ++i) - std::swap(buffer[buffer.size()-BS+i], buffer[buffer.size()-2*BS+i]); - - update(buffer, offset); - } - else - { - const size_t full_blocks = ((sz / BS) - 1) * BS; - const size_t final_bytes = sz - full_blocks; - BOTAN_ASSERT(final_bytes > BS && final_bytes < 2*BS, "Left over size in expected range"); - - secure_vector last(buf + full_blocks, buf + full_blocks + final_bytes); - buffer.resize(full_blocks + offset); - update(buffer, offset); - - cipher().decrypt(last.data()); - - xor_buf(last.data(), &last[BS], final_bytes - BS); - - for(size_t i = 0; i != final_bytes - BS; ++i) - std::swap(last[i], last[i + BS]); - - cipher().decrypt(last.data()); - xor_buf(last.data(), state_ptr(), BS); - - buffer += last; - } - } - +CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) + : m_cipher(cipher), m_padding(padding), m_block_size(cipher->block_size()) { + if (m_padding && !m_padding->valid_blocksize(m_block_size)) + throw Invalid_Argument("Padding " + m_padding->name() + " cannot be used with " + + cipher->name() + "/CBC"); } -/* -* CBC-MAC -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +void CBC_Mode::clear() { + m_cipher->clear(); + reset(); +} + +void CBC_Mode::reset() { m_state.clear(); } + +std::string CBC_Mode::name() const { + if (m_padding) + return cipher().name() + "/CBC/" + padding().name(); + else + return cipher().name() + "/CBC/CTS"; +} + +size_t CBC_Mode::update_granularity() const { return cipher().parallel_bytes(); } + +Key_Length_Specification CBC_Mode::key_spec() const { return cipher().key_spec(); } + +size_t CBC_Mode::default_nonce_length() const { return block_size(); } + +bool CBC_Mode::valid_nonce_length(size_t n) const { return (n == 0 || n == block_size()); } + +void CBC_Mode::key_schedule(const uint8_t key[], size_t length) { + m_cipher->set_key(key, length); + m_state.clear(); +} + +void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) { + if (!valid_nonce_length(nonce_len)) throw Invalid_IV_Length(name(), nonce_len); + + /* + * A nonce of zero length means carry the last ciphertext value over + * as the new IV, as unfortunately some protocols require this. If + * this is the first message then we use an IV of all zeros. + */ + if (nonce_len) + m_state.assign(nonce, nonce + nonce_len); + else if (m_state.empty()) + m_state.resize(m_cipher->block_size()); + // else leave the state alone +} + +size_t CBC_Encryption::minimum_final_size() const { return 0; } + +size_t CBC_Encryption::output_length(size_t input_length) const { + if (input_length == 0) + return block_size(); + else + return round_up(input_length, block_size()); +} + +size_t CBC_Encryption::process(uint8_t buf[], size_t sz) { + BOTAN_STATE_CHECK(state().empty() == false); + const size_t BS = block_size(); + + BOTAN_ASSERT(sz % BS == 0, "CBC input is full blocks"); + const size_t blocks = sz / BS; + + if (blocks > 0) { + xor_buf(&buf[0], state_ptr(), BS); + cipher().encrypt(&buf[0]); + + for (size_t i = 1; i != blocks; ++i) { + xor_buf(&buf[BS * i], &buf[BS * (i - 1)], BS); + cipher().encrypt(&buf[BS * i]); + } + + state().assign(&buf[BS * (blocks - 1)], &buf[BS * blocks]); + } + + return sz; +} + +void CBC_Encryption::finish(secure_vector& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + + const size_t BS = block_size(); + + const size_t bytes_in_final_block = (buffer.size() - offset) % BS; + + padding().add_padding(buffer, bytes_in_final_block, BS); + + if ((buffer.size() - offset) % BS) + throw Internal_Error("Did not pad to full block size in " + name()); + + update(buffer, offset); +} + +bool CTS_Encryption::valid_nonce_length(size_t n) const { return (n == block_size()); } + +size_t CTS_Encryption::minimum_final_size() const { return block_size() + 1; } + +size_t CTS_Encryption::output_length(size_t input_length) const { + return input_length; // no ciphertext expansion in CTS +} + +void CTS_Encryption::finish(secure_vector& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + uint8_t* buf = buffer.data() + offset; + const size_t sz = buffer.size() - offset; + + const size_t BS = block_size(); + + if (sz < BS + 1) throw Encoding_Error(name() + ": insufficient data to encrypt"); + + if (sz % BS == 0) { + update(buffer, offset); + + // swap last two blocks + for (size_t i = 0; i != BS; ++i) + std::swap(buffer[buffer.size() - BS + i], buffer[buffer.size() - 2 * BS + i]); + } else { + const size_t full_blocks = ((sz / BS) - 1) * BS; + const size_t final_bytes = sz - full_blocks; + BOTAN_ASSERT(final_bytes > BS && final_bytes < 2 * BS, "Left over size in expected range"); + + secure_vector last(buf + full_blocks, buf + full_blocks + final_bytes); + buffer.resize(full_blocks + offset); + update(buffer, offset); + + xor_buf(last.data(), state_ptr(), BS); + cipher().encrypt(last.data()); + + for (size_t i = 0; i != final_bytes - BS; ++i) { + last[i] ^= last[i + BS]; + last[i + BS] ^= last[i]; + } + + cipher().encrypt(last.data()); + + buffer += last; + } +} + +size_t CBC_Decryption::output_length(size_t input_length) const { + return input_length; // precise for CTS, worst case otherwise +} + +size_t CBC_Decryption::minimum_final_size() const { return block_size(); } + +size_t CBC_Decryption::process(uint8_t buf[], size_t sz) { + BOTAN_STATE_CHECK(state().empty() == false); + + const size_t BS = block_size(); + + BOTAN_ASSERT(sz % BS == 0, "Input is full blocks"); + size_t blocks = sz / BS; + + while (blocks) { + const size_t to_proc = std::min(BS * blocks, m_tempbuf.size()); + + cipher().decrypt_n(buf, m_tempbuf.data(), to_proc / BS); + + xor_buf(m_tempbuf.data(), state_ptr(), BS); + xor_buf(&m_tempbuf[BS], buf, to_proc - BS); + copy_mem(state_ptr(), buf + (to_proc - BS), BS); + + copy_mem(buf, m_tempbuf.data(), to_proc); + + buf += to_proc; + blocks -= to_proc / BS; + } + + return sz; +} + +void CBC_Decryption::finish(secure_vector& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + const size_t sz = buffer.size() - offset; + + const size_t BS = block_size(); + + if (sz == 0 || sz % BS) + throw Decoding_Error(name() + ": Ciphertext not a multiple of block size"); + + update(buffer, offset); + + const size_t pad_bytes = BS - padding().unpad(&buffer[buffer.size() - BS], BS); + buffer.resize(buffer.size() - pad_bytes); // remove padding + if (pad_bytes == 0 && padding().name() != "NoPadding") { + throw Decoding_Error("Invalid CBC padding"); + } +} + +void CBC_Decryption::reset() { + CBC_Mode::reset(); + zeroise(m_tempbuf); +} + +bool CTS_Decryption::valid_nonce_length(size_t n) const { return (n == block_size()); } + +size_t CTS_Decryption::minimum_final_size() const { return block_size() + 1; } + +void CTS_Decryption::finish(secure_vector& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + const size_t sz = buffer.size() - offset; + uint8_t* buf = buffer.data() + offset; + + const size_t BS = block_size(); + + if (sz < BS + 1) throw Encoding_Error(name() + ": insufficient data to decrypt"); + + if (sz % BS == 0) { + // swap last two blocks + + for (size_t i = 0; i != BS; ++i) + std::swap(buffer[buffer.size() - BS + i], buffer[buffer.size() - 2 * BS + i]); + + update(buffer, offset); + } else { + const size_t full_blocks = ((sz / BS) - 1) * BS; + const size_t final_bytes = sz - full_blocks; + BOTAN_ASSERT(final_bytes > BS && final_bytes < 2 * BS, "Left over size in expected range"); + + secure_vector last(buf + full_blocks, buf + full_blocks + final_bytes); + buffer.resize(full_blocks + offset); + update(buffer, offset); + + cipher().decrypt(last.data()); + + xor_buf(last.data(), &last[BS], final_bytes - BS); + + for (size_t i = 0; i != final_bytes - BS; ++i) std::swap(last[i], last[i + BS]); + + cipher().decrypt(last.data()); + xor_buf(last.data(), state_ptr(), BS); + + buffer += last; + } +} + +} // namespace Botan +/* + * CBC-MAC + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Update an CBC-MAC Calculation -*/ -void CBC_MAC::add_data(const uint8_t input[], size_t length) - { - verify_key_set(m_state.empty() == false); + * Update an CBC-MAC Calculation + */ +void CBC_MAC::add_data(const uint8_t input[], size_t length) { + verify_key_set(m_state.empty() == false); - size_t xored = std::min(output_length() - m_position, length); - xor_buf(&m_state[m_position], input, xored); - m_position += xored; + size_t xored = std::min(output_length() - m_position, length); + xor_buf(&m_state[m_position], input, xored); + m_position += xored; - if(m_position < output_length()) - return; + if (m_position < output_length()) return; - m_cipher->encrypt(m_state); - input += xored; - length -= xored; - while(length >= output_length()) - { - xor_buf(m_state, input, output_length()); - m_cipher->encrypt(m_state); - input += output_length(); - length -= output_length(); - } - - xor_buf(m_state, input, length); - m_position = length; - } - -/* -* Finalize an CBC-MAC Calculation -*/ -void CBC_MAC::final_result(uint8_t mac[]) - { - verify_key_set(m_state.empty() == false); - - if(m_position) - m_cipher->encrypt(m_state); - - copy_mem(mac, m_state.data(), m_state.size()); - zeroise(m_state); - m_position = 0; - } - -/* -* CBC-MAC Key Schedule -*/ -void CBC_MAC::key_schedule(const uint8_t key[], size_t length) - { - m_state.resize(m_cipher->block_size()); - m_cipher->set_key(key, length); - } - -/* -* Clear memory of sensitive data -*/ -void CBC_MAC::clear() - { - m_cipher->clear(); - zap(m_state); - m_position = 0; - } - -/* -* Return the name of this type -*/ -std::string CBC_MAC::name() const - { - return "CBC-MAC(" + m_cipher->name() + ")"; - } - -/* -* Return a clone of this object -*/ -MessageAuthenticationCode* CBC_MAC::clone() const - { - return new CBC_MAC(m_cipher->clone()); - } - -/* -* CBC-MAC Constructor -*/ -CBC_MAC::CBC_MAC(BlockCipher* cipher) : - m_cipher(cipher) - { - } + m_cipher->encrypt(m_state); + input += xored; + length -= xored; + while (length >= output_length()) { + xor_buf(m_state, input, output_length()); + m_cipher->encrypt(m_state); + input += output_length(); + length -= output_length(); + } + xor_buf(m_state, input, length); + m_position = length; } -/* -* CMAC -* (C) 1999-2007,2014 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Finalize an CBC-MAC Calculation + */ +void CBC_MAC::final_result(uint8_t mac[]) { + verify_key_set(m_state.empty() == false); + + if (m_position) m_cipher->encrypt(m_state); + + copy_mem(mac, m_state.data(), m_state.size()); + zeroise(m_state); + m_position = 0; +} + +/* + * CBC-MAC Key Schedule + */ +void CBC_MAC::key_schedule(const uint8_t key[], size_t length) { + m_state.resize(m_cipher->block_size()); + m_cipher->set_key(key, length); +} + +/* + * Clear memory of sensitive data + */ +void CBC_MAC::clear() { + m_cipher->clear(); + zap(m_state); + m_position = 0; +} + +/* + * Return the name of this type + */ +std::string CBC_MAC::name() const { return "CBC-MAC(" + m_cipher->name() + ")"; } + +/* + * Return a clone of this object + */ +MessageAuthenticationCode* CBC_MAC::clone() const { return new CBC_MAC(m_cipher->clone()); } + +/* + * CBC-MAC Constructor + */ +CBC_MAC::CBC_MAC(BlockCipher* cipher) : m_cipher(cipher) {} + +} // namespace Botan +/* + * CMAC + * (C) 1999-2007,2014 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Perform CMAC's multiplication in GF(2^n) -*/ -secure_vector CMAC::poly_double(const secure_vector& in) - { - secure_vector out(in.size()); - poly_double_n(out.data(), in.data(), out.size()); - return out; - } - -/* -* Update an CMAC Calculation -*/ -void CMAC::add_data(const uint8_t input[], size_t length) - { - const size_t bs = output_length(); - - buffer_insert(m_buffer, m_position, input, length); - if(m_position + length > bs) - { - xor_buf(m_state, m_buffer, bs); - m_cipher->encrypt(m_state); - input += (bs - m_position); - length -= (bs - m_position); - while(length > bs) - { - xor_buf(m_state, input, bs); - m_cipher->encrypt(m_state); - input += bs; - length -= bs; - } - copy_mem(m_buffer.data(), input, length); - m_position = 0; - } - m_position += length; - } - -/* -* Finalize an CMAC Calculation -*/ -void CMAC::final_result(uint8_t mac[]) - { - xor_buf(m_state, m_buffer, m_position); - - if(m_position == output_length()) - { - xor_buf(m_state, m_B, output_length()); - } - else - { - m_state[m_position] ^= 0x80; - xor_buf(m_state, m_P, output_length()); - } - - m_cipher->encrypt(m_state); - - copy_mem(mac, m_state.data(), output_length()); - - zeroise(m_state); - zeroise(m_buffer); - m_position = 0; - } - -/* -* CMAC Key Schedule -*/ -void CMAC::key_schedule(const uint8_t key[], size_t length) - { - clear(); - m_cipher->set_key(key, length); - m_cipher->encrypt(m_B); - poly_double_n(m_B.data(), m_B.size()); - poly_double_n(m_P.data(), m_B.data(), m_P.size()); - } - -/* -* Clear memory of sensitive data -*/ -void CMAC::clear() - { - m_cipher->clear(); - zeroise(m_state); - zeroise(m_buffer); - zeroise(m_B); - zeroise(m_P); - m_position = 0; - } - -/* -* Return the name of this type -*/ -std::string CMAC::name() const - { - return "CMAC(" + m_cipher->name() + ")"; - } - -/* -* Return a clone of this object -*/ -MessageAuthenticationCode* CMAC::clone() const - { - return new CMAC(m_cipher->clone()); - } - -/* -* CMAC Constructor -*/ -CMAC::CMAC(BlockCipher* cipher) : - m_cipher(cipher), - m_block_size(m_cipher->block_size()) - { - if(poly_double_supported_size(m_block_size) == false) - { - throw Invalid_Argument("CMAC cannot use the " + - std::to_string(m_block_size * 8) + - " bit cipher " + m_cipher->name()); - } - - m_state.resize(output_length()); - m_buffer.resize(output_length()); - m_B.resize(output_length()); - m_P.resize(output_length()); - m_position = 0; - } - + * Perform CMAC's multiplication in GF(2^n) + */ +secure_vector CMAC::poly_double(const secure_vector& in) { + secure_vector out(in.size()); + poly_double_n(out.data(), in.data(), out.size()); + return out; } -/* -* Runtime CPU detection -* (C) 2009,2010,2013,2017 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Update an CMAC Calculation + */ +void CMAC::add_data(const uint8_t input[], size_t length) { + const size_t bs = output_length(); + + buffer_insert(m_buffer, m_position, input, length); + if (m_position + length > bs) { + xor_buf(m_state, m_buffer, bs); + m_cipher->encrypt(m_state); + input += (bs - m_position); + length -= (bs - m_position); + while (length > bs) { + xor_buf(m_state, input, bs); + m_cipher->encrypt(m_state); + input += bs; + length -= bs; + } + copy_mem(m_buffer.data(), input, length); + m_position = 0; + } + m_position += length; +} + +/* + * Finalize an CMAC Calculation + */ +void CMAC::final_result(uint8_t mac[]) { + xor_buf(m_state, m_buffer, m_position); + + if (m_position == output_length()) { + xor_buf(m_state, m_B, output_length()); + } else { + m_state[m_position] ^= 0x80; + xor_buf(m_state, m_P, output_length()); + } + + m_cipher->encrypt(m_state); + + copy_mem(mac, m_state.data(), output_length()); + + zeroise(m_state); + zeroise(m_buffer); + m_position = 0; +} + +/* + * CMAC Key Schedule + */ +void CMAC::key_schedule(const uint8_t key[], size_t length) { + clear(); + m_cipher->set_key(key, length); + m_cipher->encrypt(m_B); + poly_double_n(m_B.data(), m_B.size()); + poly_double_n(m_P.data(), m_B.data(), m_P.size()); +} + +/* + * Clear memory of sensitive data + */ +void CMAC::clear() { + m_cipher->clear(); + zeroise(m_state); + zeroise(m_buffer); + zeroise(m_B); + zeroise(m_P); + m_position = 0; +} + +/* + * Return the name of this type + */ +std::string CMAC::name() const { return "CMAC(" + m_cipher->name() + ")"; } + +/* + * Return a clone of this object + */ +MessageAuthenticationCode* CMAC::clone() const { return new CMAC(m_cipher->clone()); } + +/* + * CMAC Constructor + */ +CMAC::CMAC(BlockCipher* cipher) : m_cipher(cipher), m_block_size(m_cipher->block_size()) { + if (poly_double_supported_size(m_block_size) == false) { + throw Invalid_Argument("CMAC cannot use the " + std::to_string(m_block_size * 8) + + " bit cipher " + m_cipher->name()); + } + + m_state.resize(output_length()); + m_buffer.resize(output_length()); + m_B.resize(output_length()); + m_P.resize(output_length()); + m_position = 0; +} + +} // namespace Botan +/* + * Runtime CPU detection + * (C) 2009,2010,2013,2017 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -bool CPUID::has_simd_32() - { +bool CPUID::has_simd_32() { #if defined(BOTAN_TARGET_SUPPORTS_SSE2) - return CPUID::has_sse2(); + return CPUID::has_sse2(); #elif defined(BOTAN_TARGET_SUPPORTS_ALTIVEC) - return CPUID::has_altivec(); + return CPUID::has_altivec(); #elif defined(BOTAN_TARGET_SUPPORTS_NEON) - return CPUID::has_neon(); + return CPUID::has_neon(); #else - return true; + return true; #endif - } +} -//static -std::string CPUID::to_string() - { - std::vector flags; +// static +std::string CPUID::to_string() { + std::vector flags; -#define CPUID_PRINT(flag) do { if(has_##flag()) { flags.push_back(#flag); } } while(0) +#define CPUID_PRINT(flag) \ + do { \ + if (has_##flag()) { \ + flags.push_back(#flag); \ + } \ + } while (0) #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - CPUID_PRINT(sse2); - CPUID_PRINT(ssse3); - CPUID_PRINT(sse41); - CPUID_PRINT(sse42); - CPUID_PRINT(avx2); - CPUID_PRINT(avx512f); + CPUID_PRINT(sse2); + CPUID_PRINT(ssse3); + CPUID_PRINT(sse41); + CPUID_PRINT(sse42); + CPUID_PRINT(avx2); + CPUID_PRINT(avx512f); - CPUID_PRINT(rdtsc); - CPUID_PRINT(bmi1); - CPUID_PRINT(bmi2); - CPUID_PRINT(adx); + CPUID_PRINT(rdtsc); + CPUID_PRINT(bmi1); + CPUID_PRINT(bmi2); + CPUID_PRINT(adx); - CPUID_PRINT(aes_ni); - CPUID_PRINT(clmul); - CPUID_PRINT(rdrand); - CPUID_PRINT(rdseed); - CPUID_PRINT(intel_sha); + CPUID_PRINT(aes_ni); + CPUID_PRINT(clmul); + CPUID_PRINT(rdrand); + CPUID_PRINT(rdseed); + CPUID_PRINT(intel_sha); #endif #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - CPUID_PRINT(altivec); - CPUID_PRINT(ppc_crypto); - CPUID_PRINT(darn_rng); + CPUID_PRINT(altivec); + CPUID_PRINT(ppc_crypto); + CPUID_PRINT(darn_rng); #endif #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - CPUID_PRINT(neon); - CPUID_PRINT(arm_sve); + CPUID_PRINT(neon); + CPUID_PRINT(arm_sve); - CPUID_PRINT(arm_sha1); - CPUID_PRINT(arm_sha2); - CPUID_PRINT(arm_aes); - CPUID_PRINT(arm_pmull); - CPUID_PRINT(arm_sha2_512); - CPUID_PRINT(arm_sha3); - CPUID_PRINT(arm_sm3); - CPUID_PRINT(arm_sm4); + CPUID_PRINT(arm_sha1); + CPUID_PRINT(arm_sha2); + CPUID_PRINT(arm_aes); + CPUID_PRINT(arm_pmull); + CPUID_PRINT(arm_sha2_512); + CPUID_PRINT(arm_sha3); + CPUID_PRINT(arm_sm3); + CPUID_PRINT(arm_sm4); #endif #undef CPUID_PRINT - return string_join(flags, ' '); - } + return string_join(flags, ' '); +} -//static -void CPUID::print(std::ostream& o) - { - o << "CPUID flags: " << CPUID::to_string() << "\n"; - } +// static +void CPUID::print(std::ostream& o) { o << "CPUID flags: " << CPUID::to_string() << "\n"; } -//static -void CPUID::initialize() - { - state() = CPUID_Data(); - } +// static +void CPUID::initialize() { state() = CPUID_Data(); } -CPUID::CPUID_Data::CPUID_Data() - { -#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \ - defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \ +CPUID::CPUID_Data::CPUID_Data() { +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \ defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - m_cache_line_size = 0; - m_processor_features = detect_cpu_features(&m_cache_line_size); + m_cache_line_size = 0; + m_processor_features = detect_cpu_features(&m_cache_line_size); #endif - m_processor_features |= CPUID::CPUID_INITIALIZED_BIT; + m_processor_features |= CPUID::CPUID_INITIALIZED_BIT; - if(m_cache_line_size == 0) - m_cache_line_size = BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE; + if (m_cache_line_size == 0) m_cache_line_size = BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE; - m_endian_status = runtime_check_endian(); - } + m_endian_status = runtime_check_endian(); +} -//static -CPUID::Endian_Status CPUID::CPUID_Data::runtime_check_endian() - { - // Check runtime endian - const uint32_t endian32 = 0x01234567; - const uint8_t* e8 = reinterpret_cast(&endian32); +// static +CPUID::Endian_Status CPUID::CPUID_Data::runtime_check_endian() { + // Check runtime endian + const uint32_t endian32 = 0x01234567; + const uint8_t* e8 = reinterpret_cast(&endian32); - CPUID::Endian_Status endian = CPUID::Endian_Status::Unknown; + CPUID::Endian_Status endian = CPUID::Endian_Status::Unknown; - if(e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67) - { - endian = CPUID::Endian_Status::Big; - } - else if(e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01) - { - endian = CPUID::Endian_Status::Little; - } - else - { - throw Internal_Error("Unexpected endian at runtime, neither big nor little"); - } + if (e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67) { + endian = CPUID::Endian_Status::Big; + } else if (e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01) { + endian = CPUID::Endian_Status::Little; + } else { + throw Internal_Error("Unexpected endian at runtime, neither big nor little"); + } - // If we were compiled with a known endian, verify it matches at runtime + // If we were compiled with a known endian, verify it matches at runtime #if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - BOTAN_ASSERT(endian == CPUID::Endian_Status::Little, "Build and runtime endian match"); + BOTAN_ASSERT(endian == CPUID::Endian_Status::Little, "Build and runtime endian match"); #elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - BOTAN_ASSERT(endian == CPUID::Endian_Status::Big, "Build and runtime endian match"); + BOTAN_ASSERT(endian == CPUID::Endian_Status::Big, "Build and runtime endian match"); #endif - return endian; - } + return endian; +} -std::vector -CPUID::bit_from_string(const std::string& tok) - { +std::vector CPUID::bit_from_string(const std::string& tok) { #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - if(tok == "sse2" || tok == "simd") - return {Botan::CPUID::CPUID_SSE2_BIT}; - if(tok == "ssse3") - return {Botan::CPUID::CPUID_SSSE3_BIT}; - if(tok == "aesni") - return {Botan::CPUID::CPUID_AESNI_BIT}; - if(tok == "clmul") - return {Botan::CPUID::CPUID_CLMUL_BIT}; - if(tok == "avx2") - return {Botan::CPUID::CPUID_AVX2_BIT}; - if(tok == "sha") - return {Botan::CPUID::CPUID_SHA_BIT}; - if(tok == "bmi2") - return {Botan::CPUID::CPUID_BMI2_BIT}; - if(tok == "adx") - return {Botan::CPUID::CPUID_ADX_BIT}; - if(tok == "intel_sha") - return {Botan::CPUID::CPUID_SHA_BIT}; + if (tok == "sse2" || tok == "simd") return {Botan::CPUID::CPUID_SSE2_BIT}; + if (tok == "ssse3") return {Botan::CPUID::CPUID_SSSE3_BIT}; + if (tok == "aesni") return {Botan::CPUID::CPUID_AESNI_BIT}; + if (tok == "clmul") return {Botan::CPUID::CPUID_CLMUL_BIT}; + if (tok == "avx2") return {Botan::CPUID::CPUID_AVX2_BIT}; + if (tok == "sha") return {Botan::CPUID::CPUID_SHA_BIT}; + if (tok == "bmi2") return {Botan::CPUID::CPUID_BMI2_BIT}; + if (tok == "adx") return {Botan::CPUID::CPUID_ADX_BIT}; + if (tok == "intel_sha") return {Botan::CPUID::CPUID_SHA_BIT}; #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - if(tok == "altivec" || tok == "simd") - return {Botan::CPUID::CPUID_ALTIVEC_BIT}; - if(tok == "ppc_crypto") - return {Botan::CPUID::CPUID_PPC_CRYPTO_BIT}; + if (tok == "altivec" || tok == "simd") return {Botan::CPUID::CPUID_ALTIVEC_BIT}; + if (tok == "ppc_crypto") return {Botan::CPUID::CPUID_PPC_CRYPTO_BIT}; #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - if(tok == "neon" || tok == "simd") - return {Botan::CPUID::CPUID_ARM_NEON_BIT}; - if(tok == "armv8sha1") - return {Botan::CPUID::CPUID_ARM_SHA1_BIT}; - if(tok == "armv8sha2") - return {Botan::CPUID::CPUID_ARM_SHA2_BIT}; - if(tok == "armv8aes") - return {Botan::CPUID::CPUID_ARM_AES_BIT}; - if(tok == "armv8pmull") - return {Botan::CPUID::CPUID_ARM_PMULL_BIT}; - if(tok == "armv8sha3") - return {Botan::CPUID::CPUID_ARM_SHA3_BIT}; - if(tok == "armv8sha2_512") - return {Botan::CPUID::CPUID_ARM_SHA2_512_BIT}; - if(tok == "armv8sm3") - return {Botan::CPUID::CPUID_ARM_SM3_BIT}; - if(tok == "armv8sm4") - return {Botan::CPUID::CPUID_ARM_SM4_BIT}; + if (tok == "neon" || tok == "simd") return {Botan::CPUID::CPUID_ARM_NEON_BIT}; + if (tok == "armv8sha1") return {Botan::CPUID::CPUID_ARM_SHA1_BIT}; + if (tok == "armv8sha2") return {Botan::CPUID::CPUID_ARM_SHA2_BIT}; + if (tok == "armv8aes") return {Botan::CPUID::CPUID_ARM_AES_BIT}; + if (tok == "armv8pmull") return {Botan::CPUID::CPUID_ARM_PMULL_BIT}; + if (tok == "armv8sha3") return {Botan::CPUID::CPUID_ARM_SHA3_BIT}; + if (tok == "armv8sha2_512") return {Botan::CPUID::CPUID_ARM_SHA2_512_BIT}; + if (tok == "armv8sm3") return {Botan::CPUID::CPUID_ARM_SM3_BIT}; + if (tok == "armv8sm4") return {Botan::CPUID::CPUID_ARM_SM4_BIT}; #else - BOTAN_UNUSED(tok); + BOTAN_UNUSED(tok); #endif - return {}; - } - + return {}; } -/* -* Runtime CPU detection for ARM -* (C) 2009,2010,2013,2017 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * Runtime CPU detection for ARM + * (C) 2009,2010,2013,2017 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) #if defined(BOTAN_TARGET_OS_IS_IOS) - #include - #include +#include +#include #else @@ -7053,225 +5895,217 @@ namespace Botan { namespace { -uint64_t flags_by_ios_machine_type(const std::string& machine) - { - /* - * This relies on a map of known machine names to features. This - * will quickly grow out of date as new products are introduced, but - * is apparently the best we can do for iOS. - */ +uint64_t flags_by_ios_machine_type(const std::string& machine) { + /* + * This relies on a map of known machine names to features. This + * will quickly grow out of date as new products are introduced, but + * is apparently the best we can do for iOS. + */ - struct version_info { - std::string name; - size_t min_version_neon; - size_t min_version_armv8; - }; + struct version_info { + std::string name; + size_t min_version_neon; + size_t min_version_armv8; + }; - static const version_info min_versions[] = { - { "iPhone", 2, 6 }, - { "iPad", 1, 4 }, - { "iPod", 4, 7 }, - { "AppleTV", 2, 5 }, - }; + static const version_info min_versions[] = { + {"iPhone", 2, 6}, + {"iPad", 1, 4}, + {"iPod", 4, 7}, + {"AppleTV", 2, 5}, + }; - if(machine.size() < 3) - return 0; + if (machine.size() < 3) return 0; - auto comma = machine.find(','); + auto comma = machine.find(','); - // Simulator, or something we don't know about - if(comma == std::string::npos) - return 0; + // Simulator, or something we don't know about + if (comma == std::string::npos) return 0; - std::string product = machine.substr(0, comma); + std::string product = machine.substr(0, comma); - size_t version = 0; - size_t place = 1; - while(product.size() > 1 && ::isdigit(product.back())) - { - const size_t digit = product.back() - '0'; - version += digit * place; - place *= 10; - product.pop_back(); - } + size_t version = 0; + size_t place = 1; + while (product.size() > 1 && ::isdigit(product.back())) { + const size_t digit = product.back() - '0'; + version += digit * place; + place *= 10; + product.pop_back(); + } - if(version == 0) - return 0; + if (version == 0) return 0; - for(const version_info& info : min_versions) - { - if(info.name != product) - continue; + for (const version_info& info : min_versions) { + if (info.name != product) continue; - if(version >= info.min_version_armv8) - { - return CPUID::CPUID_ARM_AES_BIT | - CPUID::CPUID_ARM_PMULL_BIT | - CPUID::CPUID_ARM_SHA1_BIT | - CPUID::CPUID_ARM_SHA2_BIT | - CPUID::CPUID_ARM_NEON_BIT; - } + if (version >= info.min_version_armv8) { + return CPUID::CPUID_ARM_AES_BIT | CPUID::CPUID_ARM_PMULL_BIT | + CPUID::CPUID_ARM_SHA1_BIT | CPUID::CPUID_ARM_SHA2_BIT | + CPUID::CPUID_ARM_NEON_BIT; + } - if(version >= info.min_version_neon) - return CPUID::CPUID_ARM_NEON_BIT; - } - - // Some other product we don't know about - return 0; - } + if (version >= info.min_version_neon) return CPUID::CPUID_ARM_NEON_BIT; + } + // Some other product we don't know about + return 0; } +} // namespace + #endif -uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size) - { - uint64_t detected_features = 0; +uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size) { + uint64_t detected_features = 0; #if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) || defined(BOTAN_TARGET_OS_HAS_ELF_AUX_INFO) - /* - * On systems with getauxval these bits should normally be defined - * in bits/auxv.h but some buggy? glibc installs seem to miss them. - * These following values are all fixed, for the Linux ELF format, - * so we just hardcode them in ARM_hwcap_bit enum. - */ + /* + * On systems with getauxval these bits should normally be defined + * in bits/auxv.h but some buggy? glibc installs seem to miss them. + * These following values are all fixed, for the Linux ELF format, + * so we just hardcode them in ARM_hwcap_bit enum. + */ - enum ARM_hwcap_bit { + enum ARM_hwcap_bit { #if defined(BOTAN_TARGET_ARCH_IS_ARM32) - NEON_bit = (1 << 12), - AES_bit = (1 << 0), - PMULL_bit = (1 << 1), - SHA1_bit = (1 << 2), - SHA2_bit = (1 << 3), + NEON_bit = (1 << 12), + AES_bit = (1 << 0), + PMULL_bit = (1 << 1), + SHA1_bit = (1 << 2), + SHA2_bit = (1 << 3), - ARCH_hwcap_neon = 16, // AT_HWCAP - ARCH_hwcap_crypto = 26, // AT_HWCAP2 + ARCH_hwcap_neon = 16, // AT_HWCAP + ARCH_hwcap_crypto = 26, // AT_HWCAP2 #elif defined(BOTAN_TARGET_ARCH_IS_ARM64) - NEON_bit = (1 << 1), - AES_bit = (1 << 3), - PMULL_bit = (1 << 4), - SHA1_bit = (1 << 5), - SHA2_bit = (1 << 6), - SHA3_bit = (1 << 17), - SM3_bit = (1 << 18), - SM4_bit = (1 << 19), - SHA2_512_bit = (1 << 21), - SVE_bit = (1 << 22), + NEON_bit = (1 << 1), + AES_bit = (1 << 3), + PMULL_bit = (1 << 4), + SHA1_bit = (1 << 5), + SHA2_bit = (1 << 6), + SHA3_bit = (1 << 17), + SM3_bit = (1 << 18), + SM4_bit = (1 << 19), + SHA2_512_bit = (1 << 21), + SVE_bit = (1 << 22), - ARCH_hwcap_neon = 16, // AT_HWCAP - ARCH_hwcap_crypto = 16, // AT_HWCAP + ARCH_hwcap_neon = 16, // AT_HWCAP + ARCH_hwcap_crypto = 16, // AT_HWCAP #endif - }; + }; #if defined(AT_DCACHEBSIZE) - // Exists only on Linux - const unsigned long dcache_line = ::getauxval(AT_DCACHEBSIZE); + // Exists only on Linux + const unsigned long dcache_line = ::getauxval(AT_DCACHEBSIZE); - // plausibility check - if(dcache_line == 32 || dcache_line == 64 || dcache_line == 128) - *cache_line_size = static_cast(dcache_line); + // plausibility check + if (dcache_line == 32 || dcache_line == 64 || dcache_line == 128) + *cache_line_size = static_cast(dcache_line); #endif - const unsigned long hwcap_neon = OS::get_auxval(ARM_hwcap_bit::ARCH_hwcap_neon); - if(hwcap_neon & ARM_hwcap_bit::NEON_bit) - detected_features |= CPUID::CPUID_ARM_NEON_BIT; + const unsigned long hwcap_neon = OS::get_auxval(ARM_hwcap_bit::ARCH_hwcap_neon); + if (hwcap_neon & ARM_hwcap_bit::NEON_bit) detected_features |= CPUID::CPUID_ARM_NEON_BIT; - /* - On aarch64 this ends up calling getauxval twice with AT_HWCAP - It doesn't seem worth optimizing this out, since getauxval is - just reading a field in the ELF header. - */ - const unsigned long hwcap_crypto = OS::get_auxval(ARM_hwcap_bit::ARCH_hwcap_crypto); - if(hwcap_crypto & ARM_hwcap_bit::AES_bit) - detected_features |= CPUID::CPUID_ARM_AES_BIT; - if(hwcap_crypto & ARM_hwcap_bit::PMULL_bit) - detected_features |= CPUID::CPUID_ARM_PMULL_BIT; - if(hwcap_crypto & ARM_hwcap_bit::SHA1_bit) - detected_features |= CPUID::CPUID_ARM_SHA1_BIT; - if(hwcap_crypto & ARM_hwcap_bit::SHA2_bit) - detected_features |= CPUID::CPUID_ARM_SHA2_BIT; + /* + On aarch64 this ends up calling getauxval twice with AT_HWCAP + It doesn't seem worth optimizing this out, since getauxval is + just reading a field in the ELF header. + */ + const unsigned long hwcap_crypto = OS::get_auxval(ARM_hwcap_bit::ARCH_hwcap_crypto); + if (hwcap_crypto & ARM_hwcap_bit::AES_bit) detected_features |= CPUID::CPUID_ARM_AES_BIT; + if (hwcap_crypto & ARM_hwcap_bit::PMULL_bit) detected_features |= CPUID::CPUID_ARM_PMULL_BIT; + if (hwcap_crypto & ARM_hwcap_bit::SHA1_bit) detected_features |= CPUID::CPUID_ARM_SHA1_BIT; + if (hwcap_crypto & ARM_hwcap_bit::SHA2_bit) detected_features |= CPUID::CPUID_ARM_SHA2_BIT; #if defined(BOTAN_TARGET_ARCH_IS_ARM64) - if(hwcap_crypto & ARM_hwcap_bit::SHA3_bit) - detected_features |= CPUID::CPUID_ARM_SHA3_BIT; - if(hwcap_crypto & ARM_hwcap_bit::SM3_bit) - detected_features |= CPUID::CPUID_ARM_SM3_BIT; - if(hwcap_crypto & ARM_hwcap_bit::SM4_bit) - detected_features |= CPUID::CPUID_ARM_SM4_BIT; - if(hwcap_crypto & ARM_hwcap_bit::SHA2_512_bit) - detected_features |= CPUID::CPUID_ARM_SHA2_512_BIT; - if(hwcap_crypto & ARM_hwcap_bit::SVE_bit) - detected_features |= CPUID::CPUID_ARM_SVE_BIT; + if (hwcap_crypto & ARM_hwcap_bit::SHA3_bit) detected_features |= CPUID::CPUID_ARM_SHA3_BIT; + if (hwcap_crypto & ARM_hwcap_bit::SM3_bit) detected_features |= CPUID::CPUID_ARM_SM3_BIT; + if (hwcap_crypto & ARM_hwcap_bit::SM4_bit) detected_features |= CPUID::CPUID_ARM_SM4_BIT; + if (hwcap_crypto & ARM_hwcap_bit::SHA2_512_bit) + detected_features |= CPUID::CPUID_ARM_SHA2_512_BIT; + if (hwcap_crypto & ARM_hwcap_bit::SVE_bit) detected_features |= CPUID::CPUID_ARM_SVE_BIT; #endif #elif defined(BOTAN_TARGET_OS_IS_IOS) - char machine[64] = { 0 }; - size_t size = sizeof(machine) - 1; - ::sysctlbyname("hw.machine", machine, &size, nullptr, 0); + char machine[64] = {0}; + size_t size = sizeof(machine) - 1; + ::sysctlbyname("hw.machine", machine, &size, nullptr, 0); - detected_features = flags_by_ios_machine_type(machine); + detected_features = flags_by_ios_machine_type(machine); #elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_ARCH_IS_ARM64) - /* - No getauxval API available, fall back on probe functions. We only - bother with Aarch64 here to simplify the code and because going to - extreme contortions to support detect NEON on devices that probably - don't support it doesn't seem worthwhile. + /* + No getauxval API available, fall back on probe functions. We only + bother with Aarch64 here to simplify the code and because going to + extreme contortions to support detect NEON on devices that probably + don't support it doesn't seem worthwhile. - NEON registers v0-v7 are caller saved in Aarch64 - */ + NEON registers v0-v7 are caller saved in Aarch64 + */ - auto neon_probe = []() -> int { asm("and v0.16b, v0.16b, v0.16b"); return 1; }; - auto aes_probe = []() -> int { asm(".word 0x4e284800"); return 1; }; - auto pmull_probe = []() -> int { asm(".word 0x0ee0e000"); return 1; }; - auto sha1_probe = []() -> int { asm(".word 0x5e280800"); return 1; }; - auto sha2_probe = []() -> int { asm(".word 0x5e282800"); return 1; }; + auto neon_probe = []() -> int { + asm("and v0.16b, v0.16b, v0.16b"); + return 1; + }; + auto aes_probe = []() -> int { + asm(".word 0x4e284800"); + return 1; + }; + auto pmull_probe = []() -> int { + asm(".word 0x0ee0e000"); + return 1; + }; + auto sha1_probe = []() -> int { + asm(".word 0x5e280800"); + return 1; + }; + auto sha2_probe = []() -> int { + asm(".word 0x5e282800"); + return 1; + }; - // Only bother running the crypto detection if we found NEON + // Only bother running the crypto detection if we found NEON - if(OS::run_cpu_instruction_probe(neon_probe) == 1) - { - detected_features |= CPUID::CPUID_ARM_NEON_BIT; + if (OS::run_cpu_instruction_probe(neon_probe) == 1) { + detected_features |= CPUID::CPUID_ARM_NEON_BIT; - if(OS::run_cpu_instruction_probe(aes_probe) == 1) - detected_features |= CPUID::CPUID_ARM_AES_BIT; - if(OS::run_cpu_instruction_probe(pmull_probe) == 1) - detected_features |= CPUID::CPUID_ARM_PMULL_BIT; - if(OS::run_cpu_instruction_probe(sha1_probe) == 1) - detected_features |= CPUID::CPUID_ARM_SHA1_BIT; - if(OS::run_cpu_instruction_probe(sha2_probe) == 1) - detected_features |= CPUID::CPUID_ARM_SHA2_BIT; - } - -#endif - - return detected_features; - } + if (OS::run_cpu_instruction_probe(aes_probe) == 1) + detected_features |= CPUID::CPUID_ARM_AES_BIT; + if (OS::run_cpu_instruction_probe(pmull_probe) == 1) + detected_features |= CPUID::CPUID_ARM_PMULL_BIT; + if (OS::run_cpu_instruction_probe(sha1_probe) == 1) + detected_features |= CPUID::CPUID_ARM_SHA1_BIT; + if (OS::run_cpu_instruction_probe(sha2_probe) == 1) + detected_features |= CPUID::CPUID_ARM_SHA2_BIT; + } #endif + return detected_features; } -/* -* Runtime CPU detection for POWER/PowerPC -* (C) 2009,2010,2013,2017 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +#endif + +} // namespace Botan +/* + * Runtime CPU detection for POWER/PowerPC + * (C) 2009,2010,2013,2017 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) /* -* On macOS and OpenBSD ppc, use sysctl to detect AltiVec -*/ + * On macOS and OpenBSD ppc, use sysctl to detect AltiVec + */ #if defined(BOTAN_TARGET_OS_IS_MACOS) - #include +#include #elif defined(BOTAN_TARGET_OS_IS_OPENBSD) - #include - #include - #include +#include +#include +#include #endif #endif @@ -7281,140 +6115,131 @@ namespace Botan { #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) /* -* PowerPC specific block: check for AltiVec using either -* sysctl or by reading processor version number register. -*/ -uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size) - { - BOTAN_UNUSED(cache_line_size); + * PowerPC specific block: check for AltiVec using either + * sysctl or by reading processor version number register. + */ +uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size) { + BOTAN_UNUSED(cache_line_size); #if defined(BOTAN_TARGET_OS_IS_MACOS) || defined(BOTAN_TARGET_OS_IS_OPENBSD) - // On macOS and OpenBSD, use sysctl + // On macOS and OpenBSD, use sysctl - int sels[2] = { + int sels[2] = { #if defined(BOTAN_TARGET_OS_IS_OPENBSD) - CTL_MACHDEP, CPU_ALTIVEC + CTL_MACHDEP, CPU_ALTIVEC #else - CTL_HW, HW_VECTORUNIT + CTL_HW, HW_VECTORUNIT #endif - }; + }; - int vector_type = 0; - size_t length = sizeof(vector_type); - int error = ::sysctl(sels, 2, &vector_type, &length, NULL, 0); + int vector_type = 0; + size_t length = sizeof(vector_type); + int error = ::sysctl(sels, 2, &vector_type, &length, NULL, 0); - if(error == 0 && vector_type > 0) - return CPUID::CPUID_ALTIVEC_BIT; + if (error == 0 && vector_type > 0) return CPUID::CPUID_ALTIVEC_BIT; -#elif (defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) || defined(BOTAN_TARGET_HAS_ELF_AUX_INFO)) && defined(BOTAN_TARGET_ARCH_IS_PPC64) +#elif (defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) || defined(BOTAN_TARGET_HAS_ELF_AUX_INFO)) && \ + defined(BOTAN_TARGET_ARCH_IS_PPC64) - enum PPC_hwcap_bit { - ALTIVEC_bit = (1 << 28), - CRYPTO_bit = (1 << 25), - DARN_bit = (1 << 21), + enum PPC_hwcap_bit { + ALTIVEC_bit = (1 << 28), + CRYPTO_bit = (1 << 25), + DARN_bit = (1 << 21), - ARCH_hwcap_altivec = 16, // AT_HWCAP - ARCH_hwcap_crypto = 26, // AT_HWCAP2 - }; + ARCH_hwcap_altivec = 16, // AT_HWCAP + ARCH_hwcap_crypto = 26, // AT_HWCAP2 + }; - uint64_t detected_features = 0; + uint64_t detected_features = 0; - const unsigned long hwcap_altivec = OS::get_auxval(PPC_hwcap_bit::ARCH_hwcap_altivec); - if(hwcap_altivec & PPC_hwcap_bit::ALTIVEC_bit) - detected_features |= CPUID::CPUID_ALTIVEC_BIT; + const unsigned long hwcap_altivec = OS::get_auxval(PPC_hwcap_bit::ARCH_hwcap_altivec); + if (hwcap_altivec & PPC_hwcap_bit::ALTIVEC_bit) detected_features |= CPUID::CPUID_ALTIVEC_BIT; - const unsigned long hwcap_crypto = OS::get_auxval(PPC_hwcap_bit::ARCH_hwcap_crypto); - if(hwcap_crypto & PPC_hwcap_bit::CRYPTO_bit) - detected_features |= CPUID::CPUID_PPC_CRYPTO_BIT; - if(hwcap_crypto & PPC_hwcap_bit::DARN_bit) - detected_features |= CPUID::CPUID_DARN_BIT; + const unsigned long hwcap_crypto = OS::get_auxval(PPC_hwcap_bit::ARCH_hwcap_crypto); + if (hwcap_crypto & PPC_hwcap_bit::CRYPTO_bit) detected_features |= CPUID::CPUID_PPC_CRYPTO_BIT; + if (hwcap_crypto & PPC_hwcap_bit::DARN_bit) detected_features |= CPUID::CPUID_DARN_BIT; - return detected_features; + return detected_features; #else - /* - On PowerPC, MSR 287 is PVR, the Processor Version Number - Normally it is only accessible to ring 0, but Linux and NetBSD - (others, too, maybe?) will trap and emulate it for us. - */ + /* + On PowerPC, MSR 287 is PVR, the Processor Version Number + Normally it is only accessible to ring 0, but Linux and NetBSD + (others, too, maybe?) will trap and emulate it for us. + */ - int pvr = OS::run_cpu_instruction_probe([]() -> int { - uint32_t pvr = 0; - asm volatile("mfspr %0, 287" : "=r" (pvr)); - // Top 16 bits suffice to identify the model - return static_cast(pvr >> 16); - }); + int pvr = OS::run_cpu_instruction_probe([]() -> int { + uint32_t pvr = 0; + asm volatile("mfspr %0, 287" : "=r"(pvr)); + // Top 16 bits suffice to identify the model + return static_cast(pvr >> 16); + }); - if(pvr > 0) - { - const uint16_t ALTIVEC_PVR[] = { - 0x003E, // IBM POWER6 - 0x003F, // IBM POWER7 - 0x004A, // IBM POWER7p - 0x004B, // IBM POWER8E - 0x004C, // IBM POWER8 NVL - 0x004D, // IBM POWER8 - 0x004E, // IBM POWER9 - 0x000C, // G4-7400 - 0x0039, // G5 970 - 0x003C, // G5 970FX - 0x0044, // G5 970MP - 0x0070, // Cell PPU - 0, // end - }; + if (pvr > 0) { + const uint16_t ALTIVEC_PVR[] = { + 0x003E, // IBM POWER6 + 0x003F, // IBM POWER7 + 0x004A, // IBM POWER7p + 0x004B, // IBM POWER8E + 0x004C, // IBM POWER8 NVL + 0x004D, // IBM POWER8 + 0x004E, // IBM POWER9 + 0x000C, // G4-7400 + 0x0039, // G5 970 + 0x003C, // G5 970FX + 0x0044, // G5 970MP + 0x0070, // Cell PPU + 0, // end + }; - for(size_t i = 0; ALTIVEC_PVR[i]; ++i) - { - if(pvr == ALTIVEC_PVR[i]) - return CPUID::CPUID_ALTIVEC_BIT; - } + for (size_t i = 0; ALTIVEC_PVR[i]; ++i) { + if (pvr == ALTIVEC_PVR[i]) return CPUID::CPUID_ALTIVEC_BIT; + } - return 0; - } + return 0; + } - // TODO try direct instruction probing - -#endif - - return 0; - } + // TODO try direct instruction probing #endif + return 0; } -/* -* Runtime CPU detection for x86 -* (C) 2009,2010,2013,2017 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +#endif + +} // namespace Botan +/* + * Runtime CPU detection for x86 + * (C) 2009,2010,2013,2017 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) - #include +#include #elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) - #include +#include #elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 430) - // Only available starting in GCC 4.3 - #include + // Only available starting in GCC 4.3 +#include namespace { - /* - * Prevent inlining to work around GCC bug 44174 - */ - [[maybe_unused]] void __attribute__((__noinline__)) call_gcc_cpuid(Botan::u32bit type, - Botan::u32bit out[4]) - { - __get_cpuid(type, out, out+1, out+2, out+3); - } - - #define CALL_CPUID call_gcc_cpuid - +/* + * Prevent inlining to work around GCC bug 44174 + */ +[[maybe_unused]] void __attribute__((__noinline__)) call_gcc_cpuid(Botan::u32bit type, + Botan::u32bit out[4]) { + __get_cpuid(type, out, out + 1, out + 2, out + 3); } + +#define CALL_CPUID call_gcc_cpuid + +} // namespace #endif #endif @@ -7423,164 +6248,164 @@ namespace Botan { #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) -uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size) - { +uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size) { #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) - #define X86_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) - #define X86_CPUID_SUBLEVEL(type, level, out) do { __cpuidex((int*)out, type, level); } while(0) +#define X86_CPUID(type, out) \ + do { \ + __cpuid((int*)out, type); \ + } while (0) +#define X86_CPUID_SUBLEVEL(type, level, out) \ + do { \ + __cpuidex((int*)out, type, level); \ + } while (0) #elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) - #define X86_CPUID(type, out) do { __cpuid(out, type); } while(0) - #define X86_CPUID_SUBLEVEL(type, level, out) do { __cpuidex((int*)out, type, level); } while(0) +#define X86_CPUID(type, out) \ + do { \ + __cpuid(out, type); \ + } while (0) +#define X86_CPUID_SUBLEVEL(type, level, out) \ + do { \ + __cpuidex((int*)out, type, level); \ + } while (0) #elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && defined(BOTAN_USE_GCC_INLINE_ASM) - #define X86_CPUID(type, out) \ - asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ - : "0" (type)) +#define X86_CPUID(type, out) \ + asm("cpuid\n\t" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "0"(type)) - #define X86_CPUID_SUBLEVEL(type, level, out) \ - asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ - : "0" (type), "2" (level)) +#define X86_CPUID_SUBLEVEL(type, level, out) \ + asm("cpuid\n\t" \ + : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) \ + : "0"(type), "2"(level)) #elif defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) - #define X86_CPUID(type, out) do { __get_cpuid(type, out, out+1, out+2, out+3); } while(0) +#define X86_CPUID(type, out) \ + do { \ + __get_cpuid(type, out, out + 1, out + 2, out + 3); \ + } while (0) - #define X86_CPUID_SUBLEVEL(type, level, out) \ - do { __cpuid_count(type, level, out[0], out[1], out[2], out[3]); } while(0) +#define X86_CPUID_SUBLEVEL(type, level, out) \ + do { \ + __cpuid_count(type, level, out[0], out[1], out[2], out[3]); \ + } while (0) #else - #warning "No way of calling x86 cpuid instruction for this compiler" - #define X86_CPUID(type, out) do { clear_mem(out, 4); } while(0) - #define X86_CPUID_SUBLEVEL(type, level, out) do { clear_mem(out, 4); } while(0) +#warning "No way of calling x86 cpuid instruction for this compiler" +#define X86_CPUID(type, out) \ + do { \ + clear_mem(out, 4); \ + } while (0) +#define X86_CPUID_SUBLEVEL(type, level, out) \ + do { \ + clear_mem(out, 4); \ + } while (0) #endif - uint64_t features_detected = 0; - uint32_t cpuid[4] = { 0 }; + uint64_t features_detected = 0; + uint32_t cpuid[4] = {0}; - // CPUID 0: vendor identification, max sublevel - X86_CPUID(0, cpuid); + // CPUID 0: vendor identification, max sublevel + X86_CPUID(0, cpuid); - const uint32_t max_supported_sublevel = cpuid[0]; + const uint32_t max_supported_sublevel = cpuid[0]; - const uint32_t INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; - const uint32_t AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; - const bool is_intel = same_mem(cpuid + 1, INTEL_CPUID, 3); - const bool is_amd = same_mem(cpuid + 1, AMD_CPUID, 3); + const uint32_t INTEL_CPUID[3] = {0x756E6547, 0x6C65746E, 0x49656E69}; + const uint32_t AMD_CPUID[3] = {0x68747541, 0x444D4163, 0x69746E65}; + const bool is_intel = same_mem(cpuid + 1, INTEL_CPUID, 3); + const bool is_amd = same_mem(cpuid + 1, AMD_CPUID, 3); - if(max_supported_sublevel >= 1) - { - // CPUID 1: feature bits - X86_CPUID(1, cpuid); - const uint64_t flags0 = (static_cast(cpuid[2]) << 32) | cpuid[3]; + if (max_supported_sublevel >= 1) { + // CPUID 1: feature bits + X86_CPUID(1, cpuid); + const uint64_t flags0 = (static_cast(cpuid[2]) << 32) | cpuid[3]; - enum x86_CPUID_1_bits : uint64_t { - RDTSC = (1ULL << 4), - SSE2 = (1ULL << 26), - CLMUL = (1ULL << 33), - SSSE3 = (1ULL << 41), - SSE41 = (1ULL << 51), - SSE42 = (1ULL << 52), - AESNI = (1ULL << 57), - RDRAND = (1ULL << 62) - }; + enum x86_CPUID_1_bits : uint64_t { + RDTSC = (1ULL << 4), + SSE2 = (1ULL << 26), + CLMUL = (1ULL << 33), + SSSE3 = (1ULL << 41), + SSE41 = (1ULL << 51), + SSE42 = (1ULL << 52), + AESNI = (1ULL << 57), + RDRAND = (1ULL << 62) + }; - if(flags0 & x86_CPUID_1_bits::RDTSC) - features_detected |= CPUID::CPUID_RDTSC_BIT; - if(flags0 & x86_CPUID_1_bits::SSE2) - features_detected |= CPUID::CPUID_SSE2_BIT; - if(flags0 & x86_CPUID_1_bits::CLMUL) - features_detected |= CPUID::CPUID_CLMUL_BIT; - if(flags0 & x86_CPUID_1_bits::SSSE3) - features_detected |= CPUID::CPUID_SSSE3_BIT; - if(flags0 & x86_CPUID_1_bits::SSE41) - features_detected |= CPUID::CPUID_SSE41_BIT; - if(flags0 & x86_CPUID_1_bits::SSE42) - features_detected |= CPUID::CPUID_SSE42_BIT; - if(flags0 & x86_CPUID_1_bits::AESNI) - features_detected |= CPUID::CPUID_AESNI_BIT; - if(flags0 & x86_CPUID_1_bits::RDRAND) - features_detected |= CPUID::CPUID_RDRAND_BIT; - } + if (flags0 & x86_CPUID_1_bits::RDTSC) features_detected |= CPUID::CPUID_RDTSC_BIT; + if (flags0 & x86_CPUID_1_bits::SSE2) features_detected |= CPUID::CPUID_SSE2_BIT; + if (flags0 & x86_CPUID_1_bits::CLMUL) features_detected |= CPUID::CPUID_CLMUL_BIT; + if (flags0 & x86_CPUID_1_bits::SSSE3) features_detected |= CPUID::CPUID_SSSE3_BIT; + if (flags0 & x86_CPUID_1_bits::SSE41) features_detected |= CPUID::CPUID_SSE41_BIT; + if (flags0 & x86_CPUID_1_bits::SSE42) features_detected |= CPUID::CPUID_SSE42_BIT; + if (flags0 & x86_CPUID_1_bits::AESNI) features_detected |= CPUID::CPUID_AESNI_BIT; + if (flags0 & x86_CPUID_1_bits::RDRAND) features_detected |= CPUID::CPUID_RDRAND_BIT; + } - if(is_intel) - { - // Intel cache line size is in cpuid(1) output - *cache_line_size = 8 * get_byte(2, cpuid[1]); - } - else if(is_amd) - { - // AMD puts it in vendor zone - X86_CPUID(0x80000005, cpuid); - *cache_line_size = get_byte(3, cpuid[2]); - } + if (is_intel) { + // Intel cache line size is in cpuid(1) output + *cache_line_size = 8 * get_byte(2, cpuid[1]); + } else if (is_amd) { + // AMD puts it in vendor zone + X86_CPUID(0x80000005, cpuid); + *cache_line_size = get_byte(3, cpuid[2]); + } - if(max_supported_sublevel >= 7) - { - clear_mem(cpuid, 4); - X86_CPUID_SUBLEVEL(7, 0, cpuid); + if (max_supported_sublevel >= 7) { + clear_mem(cpuid, 4); + X86_CPUID_SUBLEVEL(7, 0, cpuid); - enum x86_CPUID_7_bits : uint64_t { - BMI1 = (1ULL << 3), - AVX2 = (1ULL << 5), - BMI2 = (1ULL << 8), - AVX512F = (1ULL << 16), - RDSEED = (1ULL << 18), - ADX = (1ULL << 19), - SHA = (1ULL << 29), - }; - uint64_t flags7 = (static_cast(cpuid[2]) << 32) | cpuid[1]; + enum x86_CPUID_7_bits : uint64_t { + BMI1 = (1ULL << 3), + AVX2 = (1ULL << 5), + BMI2 = (1ULL << 8), + AVX512F = (1ULL << 16), + RDSEED = (1ULL << 18), + ADX = (1ULL << 19), + SHA = (1ULL << 29), + }; + uint64_t flags7 = (static_cast(cpuid[2]) << 32) | cpuid[1]; - if(flags7 & x86_CPUID_7_bits::AVX2) - features_detected |= CPUID::CPUID_AVX2_BIT; - if(flags7 & x86_CPUID_7_bits::BMI1) - { - features_detected |= CPUID::CPUID_BMI1_BIT; - /* - We only set the BMI2 bit if BMI1 is also supported, so BMI2 - code can safely use both extensions. No known processor - implements BMI2 but not BMI1. - */ - if(flags7 & x86_CPUID_7_bits::BMI2) - features_detected |= CPUID::CPUID_BMI2_BIT; - } + if (flags7 & x86_CPUID_7_bits::AVX2) features_detected |= CPUID::CPUID_AVX2_BIT; + if (flags7 & x86_CPUID_7_bits::BMI1) { + features_detected |= CPUID::CPUID_BMI1_BIT; + /* + We only set the BMI2 bit if BMI1 is also supported, so BMI2 + code can safely use both extensions. No known processor + implements BMI2 but not BMI1. + */ + if (flags7 & x86_CPUID_7_bits::BMI2) features_detected |= CPUID::CPUID_BMI2_BIT; + } - if(flags7 & x86_CPUID_7_bits::AVX512F) - features_detected |= CPUID::CPUID_AVX512F_BIT; - if(flags7 & x86_CPUID_7_bits::RDSEED) - features_detected |= CPUID::CPUID_RDSEED_BIT; - if(flags7 & x86_CPUID_7_bits::ADX) - features_detected |= CPUID::CPUID_ADX_BIT; - if(flags7 & x86_CPUID_7_bits::SHA) - features_detected |= CPUID::CPUID_SHA_BIT; - } + if (flags7 & x86_CPUID_7_bits::AVX512F) features_detected |= CPUID::CPUID_AVX512F_BIT; + if (flags7 & x86_CPUID_7_bits::RDSEED) features_detected |= CPUID::CPUID_RDSEED_BIT; + if (flags7 & x86_CPUID_7_bits::ADX) features_detected |= CPUID::CPUID_ADX_BIT; + if (flags7 & x86_CPUID_7_bits::SHA) features_detected |= CPUID::CPUID_SHA_BIT; + } #undef X86_CPUID #undef X86_CPUID_SUBLEVEL - /* - * If we don't have access to CPUID, we can still safely assume that - * any x86-64 processor has SSE2 and RDTSC - */ + /* + * If we don't have access to CPUID, we can still safely assume that + * any x86-64 processor has SSE2 and RDTSC + */ #if defined(BOTAN_TARGET_ARCH_IS_X86_64) - if(features_detected == 0) - { - features_detected |= CPUID::CPUID_SSE2_BIT; - features_detected |= CPUID::CPUID_RDTSC_BIT; - } -#endif - - return features_detected; - } - + if (features_detected == 0) { + features_detected |= CPUID::CPUID_SSE2_BIT; + features_detected |= CPUID::CPUID_RDTSC_BIT; + } #endif + return features_detected; } -/* -* Entropy Source Polling -* (C) 2008-2010,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +#endif + +} // namespace Botan +/* + * Entropy Source Polling + * (C) 2008-2010,2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_SYSTEM_RNG) #endif @@ -7612,687 +6437,573 @@ namespace Botan { namespace { -class System_RNG_EntropySource final : public Entropy_Source - { +class System_RNG_EntropySource final : public Entropy_Source { public: - size_t poll(RandomNumberGenerator& rng) override - { - const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS; - rng.reseed_from_rng(system_rng(), poll_bits); - return poll_bits; - } + size_t poll(RandomNumberGenerator& rng) override { + const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS; + rng.reseed_from_rng(system_rng(), poll_bits); + return poll_bits; + } - std::string name() const override { return "system_rng"; } - }; + std::string name() const override { return "system_rng"; } +}; -} +} // namespace #endif -std::unique_ptr Entropy_Source::create(const std::string& name) - { +std::unique_ptr Entropy_Source::create(const std::string& name) { #if defined(BOTAN_HAS_SYSTEM_RNG) - if(name == "system_rng" || name == "win32_cryptoapi") - { - return std::unique_ptr(new System_RNG_EntropySource); - } + if (name == "system_rng" || name == "win32_cryptoapi") { + return std::unique_ptr(new System_RNG_EntropySource); + } #endif #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) - if(name == "rdrand") - { - return std::unique_ptr(new Intel_Rdrand); - } + if (name == "rdrand") { + return std::unique_ptr(new Intel_Rdrand); + } #endif #if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED) - if(name == "rdseed") - { - return std::unique_ptr(new Intel_Rdseed); - } + if (name == "rdseed") { + return std::unique_ptr(new Intel_Rdseed); + } #endif #if defined(BOTAN_HAS_ENTROPY_SRC_DARN) - if(name == "p9_darn") - { - return std::unique_ptr(new POWER9_DARN); - } + if (name == "p9_darn") { + return std::unique_ptr(new POWER9_DARN); + } #endif #if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY) - if(name == "getentropy") - { - return std::unique_ptr(new Getentropy); - } + if (name == "getentropy") { + return std::unique_ptr(new Getentropy); + } #endif #if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) - if(name == "dev_random") - { - //return std::unique_ptr(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES)); - } + if (name == "dev_random") { + // return std::unique_ptr(new + // Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES)); + } #endif #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) - if(name == "proc_walk" && OS::running_in_privileged_state() == false) - { - const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH; - if(!root_dir.empty()) - return std::unique_ptr(new ProcWalking_EntropySource(root_dir)); - } + if (name == "proc_walk" && OS::running_in_privileged_state() == false) { + const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH; + if (!root_dir.empty()) + return std::unique_ptr(new ProcWalking_EntropySource(root_dir)); + } #endif #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) - if(name == "system_stats") - { - // return std::unique_ptr(new Win32_EntropySource); - } + if (name == "system_stats") { + // return std::unique_ptr(new Win32_EntropySource); + } #endif - BOTAN_UNUSED(name); - return std::unique_ptr(); - } - -void Entropy_Sources::add_source(std::unique_ptr src) - { - if(src.get()) - { - m_srcs.push_back(std::move(src)); - } - } - -std::vector Entropy_Sources::enabled_sources() const - { - std::vector sources; - for(size_t i = 0; i != m_srcs.size(); ++i) - { - sources.push_back(m_srcs[i]->name()); - } - return sources; - } - -size_t Entropy_Sources::poll(RandomNumberGenerator& rng, - size_t poll_bits, - std::chrono::milliseconds timeout) - { - typedef std::chrono::system_clock clock; - - auto deadline = clock::now() + timeout; - - size_t bits_collected = 0; - - for(size_t i = 0; i != m_srcs.size(); ++i) - { - bits_collected += m_srcs[i]->poll(rng); - - if (bits_collected >= poll_bits || clock::now() > deadline) - break; - } - - return bits_collected; - } - -size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, const std::string& the_src) - { - for(size_t i = 0; i != m_srcs.size(); ++i) - { - if(m_srcs[i]->name() == the_src) - { - return m_srcs[i]->poll(rng); - } - } - - return 0; - } - -Entropy_Sources::Entropy_Sources(const std::vector& sources) - { - for(auto&& src_name : sources) - { - add_source(Entropy_Source::create(src_name)); - } - } - -Entropy_Sources& Entropy_Sources::global_sources() - { - static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES); - - return global_entropy_sources; - } - + BOTAN_UNUSED(name); + return std::unique_ptr(); } -/* -* Filters -* (C) 1999-2007,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +void Entropy_Sources::add_source(std::unique_ptr src) { + if (src.get()) { + m_srcs.push_back(std::move(src)); + } +} +std::vector Entropy_Sources::enabled_sources() const { + std::vector sources; + for (size_t i = 0; i != m_srcs.size(); ++i) { + sources.push_back(m_srcs[i]->name()); + } + return sources; +} + +size_t Entropy_Sources::poll(RandomNumberGenerator& rng, size_t poll_bits, + std::chrono::milliseconds timeout) { + typedef std::chrono::system_clock clock; + + auto deadline = clock::now() + timeout; + + size_t bits_collected = 0; + + for (size_t i = 0; i != m_srcs.size(); ++i) { + bits_collected += m_srcs[i]->poll(rng); + + if (bits_collected >= poll_bits || clock::now() > deadline) break; + } + + return bits_collected; +} + +size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, const std::string& the_src) { + for (size_t i = 0; i != m_srcs.size(); ++i) { + if (m_srcs[i]->name() == the_src) { + return m_srcs[i]->poll(rng); + } + } + + return 0; +} + +Entropy_Sources::Entropy_Sources(const std::vector& sources) { + for (auto&& src_name : sources) { + add_source(Entropy_Source::create(src_name)); + } +} + +Entropy_Sources& Entropy_Sources::global_sources() { + static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES); + + return global_entropy_sources; +} + +} // namespace Botan + +/* + * Filters + * (C) 1999-2007,2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { #if defined(BOTAN_HAS_STREAM_CIPHER) -StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher) : - m_buffer(BOTAN_DEFAULT_BUFFER_SIZE), - m_cipher(cipher) - { - } +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher) + : m_buffer(BOTAN_DEFAULT_BUFFER_SIZE), m_cipher(cipher) {} -StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key) : - StreamCipher_Filter(cipher) - { - m_cipher->set_key(key); - } +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key) + : StreamCipher_Filter(cipher) { + m_cipher->set_key(key); +} -StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : - m_buffer(BOTAN_DEFAULT_BUFFER_SIZE), - m_cipher(StreamCipher::create_or_throw(sc_name)) - { - } +StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) + : m_buffer(BOTAN_DEFAULT_BUFFER_SIZE), m_cipher(StreamCipher::create_or_throw(sc_name)) {} -StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, const SymmetricKey& key) : - StreamCipher_Filter(sc_name) - { - m_cipher->set_key(key); - } +StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, const SymmetricKey& key) + : StreamCipher_Filter(sc_name) { + m_cipher->set_key(key); +} -void StreamCipher_Filter::write(const uint8_t input[], size_t length) - { - while(length) - { - size_t copied = std::min(length, m_buffer.size()); - m_cipher->cipher(input, m_buffer.data(), copied); - send(m_buffer, copied); - input += copied; - length -= copied; - } - } +void StreamCipher_Filter::write(const uint8_t input[], size_t length) { + while (length) { + size_t copied = std::min(length, m_buffer.size()); + m_cipher->cipher(input, m_buffer.data(), copied); + send(m_buffer, copied); + input += copied; + length -= copied; + } +} #endif #if defined(BOTAN_HAS_HASH) -Hash_Filter::Hash_Filter(const std::string& hash_name, size_t len) : - m_hash(HashFunction::create_or_throw(hash_name)), - m_out_len(len) - { - } +Hash_Filter::Hash_Filter(const std::string& hash_name, size_t len) + : m_hash(HashFunction::create_or_throw(hash_name)), m_out_len(len) {} -void Hash_Filter::end_msg() - { - secure_vector output = m_hash->final(); - if(m_out_len) - send(output, std::min(m_out_len, output.size())); - else - send(output); - } +void Hash_Filter::end_msg() { + secure_vector output = m_hash->final(); + if (m_out_len) + send(output, std::min(m_out_len, output.size())); + else + send(output); +} #endif #if defined(BOTAN_HAS_MAC) -MAC_Filter::MAC_Filter(const std::string& mac_name, size_t len) : - m_mac(MessageAuthenticationCode::create_or_throw(mac_name)), - m_out_len(len) - { - } +MAC_Filter::MAC_Filter(const std::string& mac_name, size_t len) + : m_mac(MessageAuthenticationCode::create_or_throw(mac_name)), m_out_len(len) {} -MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, size_t len) : - MAC_Filter(mac_name, len) - { - m_mac->set_key(key); - } +MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, size_t len) + : MAC_Filter(mac_name, len) { + m_mac->set_key(key); +} -void MAC_Filter::end_msg() - { - secure_vector output = m_mac->final(); - if(m_out_len) - send(output, std::min(m_out_len, output.size())); - else - send(output); - } +void MAC_Filter::end_msg() { + secure_vector output = m_mac->final(); + if (m_out_len) + send(output, std::min(m_out_len, output.size())); + else + send(output); +} #endif -} +} // namespace Botan /* -* Base64 Encoder/Decoder -* (C) 1999-2010 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Base64 Encoder/Decoder + * (C) 1999-2010 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Base64_Encoder Constructor -*/ -Base64_Encoder::Base64_Encoder(bool breaks, size_t length, bool t_n) : - m_line_length(breaks ? length : 0), - m_trailing_newline(t_n && breaks), - m_in(48), - m_out(64), - m_position(0), - m_out_position(0) - { - } + * Base64_Encoder Constructor + */ +Base64_Encoder::Base64_Encoder(bool breaks, size_t length, bool t_n) + : m_line_length(breaks ? length : 0), + m_trailing_newline(t_n && breaks), + m_in(48), + m_out(64), + m_position(0), + m_out_position(0) {} /* -* Encode and send a block -*/ -void Base64_Encoder::encode_and_send(const uint8_t input[], size_t length, - bool final_inputs) - { - while(length) - { - const size_t proc = std::min(length, m_in.size()); + * Encode and send a block + */ +void Base64_Encoder::encode_and_send(const uint8_t input[], size_t length, bool final_inputs) { + while (length) { + const size_t proc = std::min(length, m_in.size()); - size_t consumed = 0; - size_t produced = base64_encode(cast_uint8_ptr_to_char(m_out.data()), - input, proc, consumed, final_inputs); + size_t consumed = 0; + size_t produced = base64_encode(cast_uint8_ptr_to_char(m_out.data()), input, proc, consumed, + final_inputs); - do_output(m_out.data(), produced); + do_output(m_out.data(), produced); - // FIXME: s/proc/consumed/? - input += proc; - length -= proc; - } - } + // FIXME: s/proc/consumed/? + input += proc; + length -= proc; + } +} /* -* Handle the output -*/ -void Base64_Encoder::do_output(const uint8_t input[], size_t length) - { - if(m_line_length == 0) - send(input, length); - else - { - size_t remaining = length, offset = 0; - while(remaining) - { - size_t sent = std::min(m_line_length - m_out_position, remaining); - send(input + offset, sent); - m_out_position += sent; - remaining -= sent; - offset += sent; - if(m_out_position == m_line_length) - { - send('\n'); - m_out_position = 0; + * Handle the output + */ +void Base64_Encoder::do_output(const uint8_t input[], size_t length) { + if (m_line_length == 0) + send(input, length); + else { + size_t remaining = length, offset = 0; + while (remaining) { + size_t sent = std::min(m_line_length - m_out_position, remaining); + send(input + offset, sent); + m_out_position += sent; + remaining -= sent; + offset += sent; + if (m_out_position == m_line_length) { + send('\n'); + m_out_position = 0; } - } - } - } - -/* -* Convert some data into Base64 -*/ -void Base64_Encoder::write(const uint8_t input[], size_t length) - { - buffer_insert(m_in, m_position, input, length); - if(m_position + length >= m_in.size()) - { - encode_and_send(m_in.data(), m_in.size()); - input += (m_in.size() - m_position); - length -= (m_in.size() - m_position); - while(length >= m_in.size()) - { - encode_and_send(input, m_in.size()); - input += m_in.size(); - length -= m_in.size(); - } - copy_mem(m_in.data(), input, length); - m_position = 0; - } - m_position += length; - } - -/* -* Flush buffers -*/ -void Base64_Encoder::end_msg() - { - encode_and_send(m_in.data(), m_position, true); - - if(m_trailing_newline || (m_out_position && m_line_length)) - send('\n'); - - m_out_position = m_position = 0; - } - -/* -* Base64_Decoder Constructor -*/ -Base64_Decoder::Base64_Decoder(Decoder_Checking c) : - m_checking(c), m_in(64), m_out(48), m_position(0) - { - } - -/* -* Convert some data from Base64 -*/ -void Base64_Decoder::write(const uint8_t input[], size_t length) - { - while(length) - { - size_t to_copy = std::min(length, m_in.size() - m_position); - if(to_copy == 0) - { - m_in.resize(m_in.size()*2); - m_out.resize(m_out.size()*2); - } - copy_mem(&m_in[m_position], input, to_copy); - m_position += to_copy; - - size_t consumed = 0; - size_t written = base64_decode(m_out.data(), - cast_uint8_ptr_to_char(m_in.data()), - m_position, - consumed, - false, - m_checking != FULL_CHECK); - - send(m_out, written); - - if(consumed != m_position) - { - copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed); - m_position = m_position - consumed; - } - else - m_position = 0; - - length -= to_copy; - input += to_copy; - } - } - -/* -* Flush buffers -*/ -void Base64_Decoder::end_msg() - { - size_t consumed = 0; - size_t written = base64_decode(m_out.data(), - cast_uint8_ptr_to_char(m_in.data()), - m_position, - consumed, - true, - m_checking != FULL_CHECK); - - send(m_out, written); - - const bool not_full_bytes = consumed != m_position; - - m_position = 0; - - if(not_full_bytes) - throw Invalid_Argument("Base64_Decoder: Input not full bytes"); - } - + } + } } -/* -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Convert some data into Base64 + */ +void Base64_Encoder::write(const uint8_t input[], size_t length) { + buffer_insert(m_in, m_position, input, length); + if (m_position + length >= m_in.size()) { + encode_and_send(m_in.data(), m_in.size()); + input += (m_in.size() - m_position); + length -= (m_in.size() - m_position); + while (length >= m_in.size()) { + encode_and_send(input, m_in.size()); + input += m_in.size(); + length -= m_in.size(); + } + copy_mem(m_in.data(), input, length); + m_position = 0; + } + m_position += length; +} + +/* + * Flush buffers + */ +void Base64_Encoder::end_msg() { + encode_and_send(m_in.data(), m_position, true); + + if (m_trailing_newline || (m_out_position && m_line_length)) send('\n'); + + m_out_position = m_position = 0; +} + +/* + * Base64_Decoder Constructor + */ +Base64_Decoder::Base64_Decoder(Decoder_Checking c) + : m_checking(c), m_in(64), m_out(48), m_position(0) {} + +/* + * Convert some data from Base64 + */ +void Base64_Decoder::write(const uint8_t input[], size_t length) { + while (length) { + size_t to_copy = std::min(length, m_in.size() - m_position); + if (to_copy == 0) { + m_in.resize(m_in.size() * 2); + m_out.resize(m_out.size() * 2); + } + copy_mem(&m_in[m_position], input, to_copy); + m_position += to_copy; + + size_t consumed = 0; + size_t written = base64_decode(m_out.data(), cast_uint8_ptr_to_char(m_in.data()), + m_position, consumed, false, m_checking != FULL_CHECK); + + send(m_out, written); + + if (consumed != m_position) { + copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed); + m_position = m_position - consumed; + } else + m_position = 0; + + length -= to_copy; + input += to_copy; + } +} + +/* + * Flush buffers + */ +void Base64_Decoder::end_msg() { + size_t consumed = 0; + size_t written = base64_decode(m_out.data(), cast_uint8_ptr_to_char(m_in.data()), m_position, + consumed, true, m_checking != FULL_CHECK); + + send(m_out, written); + + const bool not_full_bytes = consumed != m_position; + + m_position = 0; + + if (not_full_bytes) throw Invalid_Argument("Base64_Decoder: Input not full bytes"); +} + +} // namespace Botan +/* + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Chain Constructor -*/ -Chain::Chain(Filter* f1, Filter* f2, Filter* f3, Filter* f4) - { - if(f1) { attach(f1); incr_owns(); } - if(f2) { attach(f2); incr_owns(); } - if(f3) { attach(f3); incr_owns(); } - if(f4) { attach(f4); incr_owns(); } - } - -/* -* Chain Constructor -*/ -Chain::Chain(Filter* filters[], size_t count) - { - for(size_t j = 0; j != count; ++j) - if(filters[j]) - { - attach(filters[j]); - incr_owns(); - } - } - -/* -* Fork Constructor -*/ -Fork::Fork(Filter* f1, Filter* f2, Filter* f3, Filter* f4) - { - Filter* filters[4] = { f1, f2, f3, f4 }; - set_next(filters, 4); - } - -/* -* Fork Constructor -*/ -Fork::Fork(Filter* filters[], size_t count) - { - set_next(filters, count); - } - + * Chain Constructor + */ +Chain::Chain(Filter* f1, Filter* f2, Filter* f3, Filter* f4) { + if (f1) { + attach(f1); + incr_owns(); + } + if (f2) { + attach(f2); + incr_owns(); + } + if (f3) { + attach(f3); + incr_owns(); + } + if (f4) { + attach(f4); + incr_owns(); + } } -/* -* Buffered Filter -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Chain Constructor + */ +Chain::Chain(Filter* filters[], size_t count) { + for (size_t j = 0; j != count; ++j) + if (filters[j]) { + attach(filters[j]); + incr_owns(); + } +} + +/* + * Fork Constructor + */ +Fork::Fork(Filter* f1, Filter* f2, Filter* f3, Filter* f4) { + Filter* filters[4] = {f1, f2, f3, f4}; + set_next(filters, 4); +} + +/* + * Fork Constructor + */ +Fork::Fork(Filter* filters[], size_t count) { set_next(filters, count); } + +} // namespace Botan +/* + * Buffered Filter + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Buffered_Filter Constructor -*/ -Buffered_Filter::Buffered_Filter(size_t b, size_t f) : - m_main_block_mod(b), m_final_minimum(f) - { - if(m_main_block_mod == 0) - throw Invalid_Argument("m_main_block_mod == 0"); + * Buffered_Filter Constructor + */ +Buffered_Filter::Buffered_Filter(size_t b, size_t f) : m_main_block_mod(b), m_final_minimum(f) { + if (m_main_block_mod == 0) throw Invalid_Argument("m_main_block_mod == 0"); - if(m_final_minimum > m_main_block_mod) - throw Invalid_Argument("m_final_minimum > m_main_block_mod"); - - m_buffer.resize(2 * m_main_block_mod); - m_buffer_pos = 0; - } - -/* -* Buffer input into blocks, trying to minimize copying -*/ -void Buffered_Filter::write(const uint8_t input[], size_t input_size) - { - if(!input_size) - return; - - if(m_buffer_pos + input_size >= m_main_block_mod + m_final_minimum) - { - size_t to_copy = std::min(m_buffer.size() - m_buffer_pos, input_size); - - copy_mem(&m_buffer[m_buffer_pos], input, to_copy); - m_buffer_pos += to_copy; - - input += to_copy; - input_size -= to_copy; - - size_t total_to_consume = - round_down(std::min(m_buffer_pos, - m_buffer_pos + input_size - m_final_minimum), - m_main_block_mod); - - buffered_block(m_buffer.data(), total_to_consume); - - m_buffer_pos -= total_to_consume; - - copy_mem(m_buffer.data(), m_buffer.data() + total_to_consume, m_buffer_pos); - } - - if(input_size >= m_final_minimum) - { - size_t full_blocks = (input_size - m_final_minimum) / m_main_block_mod; - size_t to_copy = full_blocks * m_main_block_mod; - - if(to_copy) - { - buffered_block(input, to_copy); - - input += to_copy; - input_size -= to_copy; - } - } - - copy_mem(&m_buffer[m_buffer_pos], input, input_size); - m_buffer_pos += input_size; - } - -/* -* Finish/flush operation -*/ -void Buffered_Filter::end_msg() - { - if(m_buffer_pos < m_final_minimum) - throw Invalid_State("Buffered filter end_msg without enough input"); - - size_t spare_blocks = (m_buffer_pos - m_final_minimum) / m_main_block_mod; - - if(spare_blocks) - { - size_t spare_bytes = m_main_block_mod * spare_blocks; - buffered_block(m_buffer.data(), spare_bytes); - buffered_final(&m_buffer[spare_bytes], m_buffer_pos - spare_bytes); - } - else - { - buffered_final(m_buffer.data(), m_buffer_pos); - } - - m_buffer_pos = 0; - } + if (m_final_minimum > m_main_block_mod) + throw Invalid_Argument("m_final_minimum > m_main_block_mod"); + m_buffer.resize(2 * m_main_block_mod); + m_buffer_pos = 0; } -/* -* Filter interface for Cipher_Modes -* (C) 2013,2014,2017 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Buffer input into blocks, trying to minimize copying + */ +void Buffered_Filter::write(const uint8_t input[], size_t input_size) { + if (!input_size) return; + + if (m_buffer_pos + input_size >= m_main_block_mod + m_final_minimum) { + size_t to_copy = std::min(m_buffer.size() - m_buffer_pos, input_size); + + copy_mem(&m_buffer[m_buffer_pos], input, to_copy); + m_buffer_pos += to_copy; + + input += to_copy; + input_size -= to_copy; + + size_t total_to_consume = round_down( + std::min(m_buffer_pos, m_buffer_pos + input_size - m_final_minimum), m_main_block_mod); + + buffered_block(m_buffer.data(), total_to_consume); + + m_buffer_pos -= total_to_consume; + + copy_mem(m_buffer.data(), m_buffer.data() + total_to_consume, m_buffer_pos); + } + + if (input_size >= m_final_minimum) { + size_t full_blocks = (input_size - m_final_minimum) / m_main_block_mod; + size_t to_copy = full_blocks * m_main_block_mod; + + if (to_copy) { + buffered_block(input, to_copy); + + input += to_copy; + input_size -= to_copy; + } + } + + copy_mem(&m_buffer[m_buffer_pos], input, input_size); + m_buffer_pos += input_size; +} + +/* + * Finish/flush operation + */ +void Buffered_Filter::end_msg() { + if (m_buffer_pos < m_final_minimum) + throw Invalid_State("Buffered filter end_msg without enough input"); + + size_t spare_blocks = (m_buffer_pos - m_final_minimum) / m_main_block_mod; + + if (spare_blocks) { + size_t spare_bytes = m_main_block_mod * spare_blocks; + buffered_block(m_buffer.data(), spare_bytes); + buffered_final(&m_buffer[spare_bytes], m_buffer_pos - spare_bytes); + } else { + buffered_final(m_buffer.data(), m_buffer_pos); + } + + m_buffer_pos = 0; +} + +} // namespace Botan +/* + * Filter interface for Cipher_Modes + * (C) 2013,2014,2017 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { -size_t choose_update_size(size_t update_granularity) - { - const size_t target_size = 1024; +size_t choose_update_size(size_t update_granularity) { + const size_t target_size = 1024; - if(update_granularity >= target_size) - return update_granularity; - - return round_up(target_size, update_granularity); - } + if (update_granularity >= target_size) return update_granularity; + return round_up(target_size, update_granularity); } -Cipher_Mode_Filter::Cipher_Mode_Filter(Cipher_Mode* mode) : - Buffered_Filter(choose_update_size(mode->update_granularity()), - mode->minimum_final_size()), - m_mode(mode), - m_nonce(mode->default_nonce_length()), - m_buffer(m_mode->update_granularity()) - { - } +} // namespace -std::string Cipher_Mode_Filter::name() const - { - return m_mode->name(); - } +Cipher_Mode_Filter::Cipher_Mode_Filter(Cipher_Mode* mode) + : Buffered_Filter(choose_update_size(mode->update_granularity()), mode->minimum_final_size()), + m_mode(mode), + m_nonce(mode->default_nonce_length()), + m_buffer(m_mode->update_granularity()) {} -void Cipher_Mode_Filter::set_iv(const InitializationVector& iv) - { - m_nonce = unlock(iv.bits_of()); - } +std::string Cipher_Mode_Filter::name() const { return m_mode->name(); } -void Cipher_Mode_Filter::set_key(const SymmetricKey& key) - { - m_mode->set_key(key); - } +void Cipher_Mode_Filter::set_iv(const InitializationVector& iv) { m_nonce = unlock(iv.bits_of()); } -Key_Length_Specification Cipher_Mode_Filter::key_spec() const - { - return m_mode->key_spec(); - } +void Cipher_Mode_Filter::set_key(const SymmetricKey& key) { m_mode->set_key(key); } -bool Cipher_Mode_Filter::valid_iv_length(size_t length) const - { - return m_mode->valid_nonce_length(length); - } - -void Cipher_Mode_Filter::write(const uint8_t input[], size_t input_length) - { - Buffered_Filter::write(input, input_length); - } - -void Cipher_Mode_Filter::end_msg() - { - Buffered_Filter::end_msg(); - } - -void Cipher_Mode_Filter::start_msg() - { - if(m_nonce.empty() && !m_mode->valid_nonce_length(0)) - throw Invalid_State("Cipher " + m_mode->name() + " requires a fresh nonce for each message"); - - m_mode->start(m_nonce); - m_nonce.clear(); - } - -void Cipher_Mode_Filter::buffered_block(const uint8_t input[], size_t input_length) - { - while(input_length) - { - const size_t take = std::min(m_mode->update_granularity(), input_length); - - m_buffer.assign(input, input + take); - m_mode->update(m_buffer); - - send(m_buffer); - - input += take; - input_length -= take; - } - } - -void Cipher_Mode_Filter::buffered_final(const uint8_t input[], size_t input_length) - { - secure_vector buf(input, input + input_length); - m_mode->finish(buf); - send(buf); - } +Key_Length_Specification Cipher_Mode_Filter::key_spec() const { return m_mode->key_spec(); } +bool Cipher_Mode_Filter::valid_iv_length(size_t length) const { + return m_mode->valid_nonce_length(length); } + +void Cipher_Mode_Filter::write(const uint8_t input[], size_t input_length) { + Buffered_Filter::write(input, input_length); +} + +void Cipher_Mode_Filter::end_msg() { Buffered_Filter::end_msg(); } + +void Cipher_Mode_Filter::start_msg() { + if (m_nonce.empty() && !m_mode->valid_nonce_length(0)) + throw Invalid_State("Cipher " + m_mode->name() + + " requires a fresh nonce for each message"); + + m_mode->start(m_nonce); + m_nonce.clear(); +} + +void Cipher_Mode_Filter::buffered_block(const uint8_t input[], size_t input_length) { + while (input_length) { + const size_t take = std::min(m_mode->update_granularity(), input_length); + + m_buffer.assign(input, input + take); + m_mode->update(m_buffer); + + send(m_buffer); + + input += take; + input_length -= take; + } +} + +void Cipher_Mode_Filter::buffered_final(const uint8_t input[], size_t input_length) { + secure_vector buf(input, input + input_length); + m_mode->finish(buf); + send(buf); +} + +} // namespace Botan /* -* Filter interface for compression -* (C) 2014,2015,2016 Jack Lloyd -* (C) 2015 Matej Kenda -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Filter interface for compression + * (C) 2014,2015,2016 Jack Lloyd + * (C) 2015 Matej Kenda + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_COMPRESSION) #endif @@ -8301,1509 +7012,1233 @@ namespace Botan { #if defined(BOTAN_HAS_COMPRESSION) -Compression_Filter::Compression_Filter(const std::string& type, size_t level, size_t bs) : - m_comp(make_compressor(type)), - m_buffersize(std::max(bs, 256)), - m_level(level) - { - if(!m_comp) - { - throw Invalid_Argument("Compression type '" + type + "' not found"); - } - } +Compression_Filter::Compression_Filter(const std::string& type, size_t level, size_t bs) + : m_comp(make_compressor(type)), m_buffersize(std::max(bs, 256)), m_level(level) { + if (!m_comp) { + throw Invalid_Argument("Compression type '" + type + "' not found"); + } +} Compression_Filter::~Compression_Filter() { /* for unique_ptr */ } -std::string Compression_Filter::name() const - { - return m_comp->name(); - } +std::string Compression_Filter::name() const { return m_comp->name(); } -void Compression_Filter::start_msg() - { - m_comp->start(m_level); - } +void Compression_Filter::start_msg() { m_comp->start(m_level); } -void Compression_Filter::write(const uint8_t input[], size_t input_length) - { - while(input_length) - { - const size_t take = std::min(m_buffersize, input_length); - BOTAN_ASSERT(take > 0, "Consumed something"); +void Compression_Filter::write(const uint8_t input[], size_t input_length) { + while (input_length) { + const size_t take = std::min(m_buffersize, input_length); + BOTAN_ASSERT(take > 0, "Consumed something"); - m_buffer.assign(input, input + take); - m_comp->update(m_buffer); + m_buffer.assign(input, input + take); + m_comp->update(m_buffer); - send(m_buffer); + send(m_buffer); - input += take; - input_length -= take; - } - } + input += take; + input_length -= take; + } +} -void Compression_Filter::flush() - { - m_buffer.clear(); - m_comp->update(m_buffer, 0, true); - send(m_buffer); - } +void Compression_Filter::flush() { + m_buffer.clear(); + m_comp->update(m_buffer, 0, true); + send(m_buffer); +} -void Compression_Filter::end_msg() - { - m_buffer.clear(); - m_comp->finish(m_buffer); - send(m_buffer); - } +void Compression_Filter::end_msg() { + m_buffer.clear(); + m_comp->finish(m_buffer); + send(m_buffer); +} -Decompression_Filter::Decompression_Filter(const std::string& type, size_t bs) : - m_comp(make_decompressor(type)), - m_buffersize(std::max(bs, 256)) - { - if(!m_comp) - { - throw Invalid_Argument("Compression type '" + type + "' not found"); - } - } +Decompression_Filter::Decompression_Filter(const std::string& type, size_t bs) + : m_comp(make_decompressor(type)), m_buffersize(std::max(bs, 256)) { + if (!m_comp) { + throw Invalid_Argument("Compression type '" + type + "' not found"); + } +} Decompression_Filter::~Decompression_Filter() { /* for unique_ptr */ } -std::string Decompression_Filter::name() const - { - return m_comp->name(); - } +std::string Decompression_Filter::name() const { return m_comp->name(); } -void Decompression_Filter::start_msg() - { - m_comp->start(); - } +void Decompression_Filter::start_msg() { m_comp->start(); } -void Decompression_Filter::write(const uint8_t input[], size_t input_length) - { - while(input_length) - { - const size_t take = std::min(m_buffersize, input_length); - BOTAN_ASSERT(take > 0, "Consumed something"); +void Decompression_Filter::write(const uint8_t input[], size_t input_length) { + while (input_length) { + const size_t take = std::min(m_buffersize, input_length); + BOTAN_ASSERT(take > 0, "Consumed something"); - m_buffer.assign(input, input + take); - m_comp->update(m_buffer); + m_buffer.assign(input, input + take); + m_comp->update(m_buffer); - send(m_buffer); + send(m_buffer); - input += take; - input_length -= take; - } - } + input += take; + input_length -= take; + } +} -void Decompression_Filter::end_msg() - { - m_buffer.clear(); - m_comp->finish(m_buffer); - send(m_buffer); - } +void Decompression_Filter::end_msg() { + m_buffer.clear(); + m_comp->finish(m_buffer); + send(m_buffer); +} #endif -} +} // namespace Botan /* -* DataSink -* (C) 1999-2007 Jack Lloyd -* 2005 Matthew Gregan -* 2017 Philippe Lieser -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * DataSink + * (C) 1999-2007 Jack Lloyd + * 2005 Matthew Gregan + * 2017 Philippe Lieser + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) - #include +#include #endif namespace Botan { /* -* Write to a stream -*/ -void DataSink_Stream::write(const uint8_t out[], size_t length) - { - m_sink.write(cast_uint8_ptr_to_char(out), length); - if(!m_sink.good()) - throw Stream_IO_Error("DataSink_Stream: Failure writing to " + - m_identifier); - } + * Write to a stream + */ +void DataSink_Stream::write(const uint8_t out[], size_t length) { + m_sink.write(cast_uint8_ptr_to_char(out), length); + if (!m_sink.good()) + throw Stream_IO_Error("DataSink_Stream: Failure writing to " + m_identifier); +} /* -* Flush the stream -*/ -void DataSink_Stream::end_msg() - { - m_sink.flush(); - } + * Flush the stream + */ +void DataSink_Stream::end_msg() { m_sink.flush(); } /* -* DataSink_Stream Constructor -*/ -DataSink_Stream::DataSink_Stream(std::ostream& out, - const std::string& name) : - m_identifier(name), - m_sink(out) - { - } + * DataSink_Stream Constructor + */ +DataSink_Stream::DataSink_Stream(std::ostream& out, const std::string& name) + : m_identifier(name), m_sink(out) {} #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) /* -* DataSink_Stream Constructor -*/ -DataSink_Stream::DataSink_Stream(const std::string& path, - bool use_binary) : - m_identifier(path), - m_sink_memory(new std::ofstream(path, use_binary ? std::ios::binary : std::ios::out)), - m_sink(*m_sink_memory) - { - if(!m_sink.good()) - { - throw Stream_IO_Error("DataSink_Stream: Failure opening " + path); - } - } + * DataSink_Stream Constructor + */ +DataSink_Stream::DataSink_Stream(const std::string& path, bool use_binary) + : m_identifier(path), + m_sink_memory(new std::ofstream(path, use_binary ? std::ios::binary : std::ios::out)), + m_sink(*m_sink_memory) { + if (!m_sink.good()) { + throw Stream_IO_Error("DataSink_Stream: Failure opening " + path); + } +} #endif /* -* DataSink_Stream Destructor -*/ -DataSink_Stream::~DataSink_Stream() - { - // for ~unique_ptr - } - + * DataSink_Stream Destructor + */ +DataSink_Stream::~DataSink_Stream() { + // for ~unique_ptr } -/* -* Filter -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * Filter + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Filter Constructor -*/ -Filter::Filter() - { - m_next.resize(1); - m_port_num = 0; - m_filter_owns = 0; - m_owned = false; - } - -/* -* Send data to all ports -*/ -void Filter::send(const uint8_t input[], size_t length) - { - if(!length) - return; - - bool nothing_attached = true; - for(size_t j = 0; j != total_ports(); ++j) - if(m_next[j]) - { - if(m_write_queue.size()) - m_next[j]->write(m_write_queue.data(), m_write_queue.size()); - m_next[j]->write(input, length); - nothing_attached = false; - } - - if(nothing_attached) - m_write_queue += std::make_pair(input, length); - else - m_write_queue.clear(); - } - -/* -* Start a new message -*/ -void Filter::new_msg() - { - start_msg(); - for(size_t j = 0; j != total_ports(); ++j) - if(m_next[j]) - m_next[j]->new_msg(); - } - -/* -* End the current message -*/ -void Filter::finish_msg() - { - end_msg(); - for(size_t j = 0; j != total_ports(); ++j) - if(m_next[j]) - m_next[j]->finish_msg(); - } - -/* -* Attach a filter to the current port -*/ -void Filter::attach(Filter* new_filter) - { - if(new_filter) - { - Filter* last = this; - while(last->get_next()) - last = last->get_next(); - last->m_next[last->current_port()] = new_filter; - } - } - -/* -* Set the active port on a filter -*/ -void Filter::set_port(size_t new_port) - { - if(new_port >= total_ports()) - throw Invalid_Argument("Filter: Invalid port number"); - m_port_num = new_port; - } - -/* -* Return the next Filter in the logical chain -*/ -Filter* Filter::get_next() const - { - if(m_port_num < m_next.size()) - return m_next[m_port_num]; - return nullptr; - } - -/* -* Set the next Filters -*/ -void Filter::set_next(Filter* filters[], size_t size) - { - m_next.clear(); - - m_port_num = 0; - m_filter_owns = 0; - - while(size && filters && (filters[size-1] == nullptr)) - --size; - - if(filters && size) - m_next.assign(filters, filters + size); - } - -/* -* Return the total number of ports -*/ -size_t Filter::total_ports() const - { - return m_next.size(); - } - + * Filter Constructor + */ +Filter::Filter() { + m_next.resize(1); + m_port_num = 0; + m_filter_owns = 0; + m_owned = false; } -/* -* Hex Encoder/Decoder -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Send data to all ports + */ +void Filter::send(const uint8_t input[], size_t length) { + if (!length) return; + + bool nothing_attached = true; + for (size_t j = 0; j != total_ports(); ++j) + if (m_next[j]) { + if (m_write_queue.size()) m_next[j]->write(m_write_queue.data(), m_write_queue.size()); + m_next[j]->write(input, length); + nothing_attached = false; + } + + if (nothing_attached) + m_write_queue += std::make_pair(input, length); + else + m_write_queue.clear(); +} + +/* + * Start a new message + */ +void Filter::new_msg() { + start_msg(); + for (size_t j = 0; j != total_ports(); ++j) + if (m_next[j]) m_next[j]->new_msg(); +} + +/* + * End the current message + */ +void Filter::finish_msg() { + end_msg(); + for (size_t j = 0; j != total_ports(); ++j) + if (m_next[j]) m_next[j]->finish_msg(); +} + +/* + * Attach a filter to the current port + */ +void Filter::attach(Filter* new_filter) { + if (new_filter) { + Filter* last = this; + while (last->get_next()) last = last->get_next(); + last->m_next[last->current_port()] = new_filter; + } +} + +/* + * Set the active port on a filter + */ +void Filter::set_port(size_t new_port) { + if (new_port >= total_ports()) throw Invalid_Argument("Filter: Invalid port number"); + m_port_num = new_port; +} + +/* + * Return the next Filter in the logical chain + */ +Filter* Filter::get_next() const { + if (m_port_num < m_next.size()) return m_next[m_port_num]; + return nullptr; +} + +/* + * Set the next Filters + */ +void Filter::set_next(Filter* filters[], size_t size) { + m_next.clear(); + + m_port_num = 0; + m_filter_owns = 0; + + while (size && filters && (filters[size - 1] == nullptr)) --size; + + if (filters && size) m_next.assign(filters, filters + size); +} + +/* + * Return the total number of ports + */ +size_t Filter::total_ports() const { return m_next.size(); } + +} // namespace Botan +/* + * Hex Encoder/Decoder + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /** -* Size used for internal buffer in hex encoder/decoder -*/ + * Size used for internal buffer in hex encoder/decoder + */ const size_t HEX_CODEC_BUFFER_SIZE = 256; /* -* Hex_Encoder Constructor -*/ -Hex_Encoder::Hex_Encoder(bool breaks, size_t length, Case c) : - m_casing(c), m_line_length(breaks ? length : 0) - { - m_in.resize(HEX_CODEC_BUFFER_SIZE); - m_out.resize(2*m_in.size()); - m_counter = m_position = 0; - } - -/* -* Hex_Encoder Constructor -*/ -Hex_Encoder::Hex_Encoder(Case c) : m_casing(c), m_line_length(0) - { - m_in.resize(HEX_CODEC_BUFFER_SIZE); - m_out.resize(2*m_in.size()); - m_counter = m_position = 0; - } - -/* -* Encode and send a block -*/ -void Hex_Encoder::encode_and_send(const uint8_t block[], size_t length) - { - hex_encode(cast_uint8_ptr_to_char(m_out.data()), - block, length, - m_casing == Uppercase); - - if(m_line_length == 0) - send(m_out, 2*length); - else - { - size_t remaining = 2*length, offset = 0; - while(remaining) - { - size_t sent = std::min(m_line_length - m_counter, remaining); - send(&m_out[offset], sent); - m_counter += sent; - remaining -= sent; - offset += sent; - if(m_counter == m_line_length) - { - send('\n'); - m_counter = 0; - } - } - } - } - -/* -* Convert some data into hex format -*/ -void Hex_Encoder::write(const uint8_t input[], size_t length) - { - buffer_insert(m_in, m_position, input, length); - if(m_position + length >= m_in.size()) - { - encode_and_send(m_in.data(), m_in.size()); - input += (m_in.size() - m_position); - length -= (m_in.size() - m_position); - while(length >= m_in.size()) - { - encode_and_send(input, m_in.size()); - input += m_in.size(); - length -= m_in.size(); - } - copy_mem(m_in.data(), input, length); - m_position = 0; - } - m_position += length; - } - -/* -* Flush buffers -*/ -void Hex_Encoder::end_msg() - { - encode_and_send(m_in.data(), m_position); - if(m_counter && m_line_length) - send('\n'); - m_counter = m_position = 0; - } - -/* -* Hex_Decoder Constructor -*/ -Hex_Decoder::Hex_Decoder(Decoder_Checking c) : m_checking(c) - { - m_in.resize(HEX_CODEC_BUFFER_SIZE); - m_out.resize(m_in.size() / 2); - m_position = 0; - } - -/* -* Convert some data from hex format -*/ -void Hex_Decoder::write(const uint8_t input[], size_t length) - { - while(length) - { - size_t to_copy = std::min(length, m_in.size() - m_position); - copy_mem(&m_in[m_position], input, to_copy); - m_position += to_copy; - - size_t consumed = 0; - size_t written = hex_decode(m_out.data(), - cast_uint8_ptr_to_char(m_in.data()), - m_position, - consumed, - m_checking != FULL_CHECK); - - send(m_out, written); - - if(consumed != m_position) - { - copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed); - m_position = m_position - consumed; - } - else - m_position = 0; - - length -= to_copy; - input += to_copy; - } - } - -/* -* Flush buffers -*/ -void Hex_Decoder::end_msg() - { - size_t consumed = 0; - size_t written = hex_decode(m_out.data(), - cast_uint8_ptr_to_char(m_in.data()), - m_position, - consumed, - m_checking != FULL_CHECK); - - send(m_out, written); - - const bool not_full_bytes = consumed != m_position; - - m_position = 0; - - if(not_full_bytes) - throw Invalid_Argument("Hex_Decoder: Input not full bytes"); - } - + * Hex_Encoder Constructor + */ +Hex_Encoder::Hex_Encoder(bool breaks, size_t length, Case c) + : m_casing(c), m_line_length(breaks ? length : 0) { + m_in.resize(HEX_CODEC_BUFFER_SIZE); + m_out.resize(2 * m_in.size()); + m_counter = m_position = 0; } -/* -* Pipe Output Buffer -* (C) 1999-2007,2011 Jack Lloyd -* 2012 Markus Wanner -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Hex_Encoder Constructor + */ +Hex_Encoder::Hex_Encoder(Case c) : m_casing(c), m_line_length(0) { + m_in.resize(HEX_CODEC_BUFFER_SIZE); + m_out.resize(2 * m_in.size()); + m_counter = m_position = 0; +} + +/* + * Encode and send a block + */ +void Hex_Encoder::encode_and_send(const uint8_t block[], size_t length) { + hex_encode(cast_uint8_ptr_to_char(m_out.data()), block, length, m_casing == Uppercase); + + if (m_line_length == 0) + send(m_out, 2 * length); + else { + size_t remaining = 2 * length, offset = 0; + while (remaining) { + size_t sent = std::min(m_line_length - m_counter, remaining); + send(&m_out[offset], sent); + m_counter += sent; + remaining -= sent; + offset += sent; + if (m_counter == m_line_length) { + send('\n'); + m_counter = 0; + } + } + } +} + +/* + * Convert some data into hex format + */ +void Hex_Encoder::write(const uint8_t input[], size_t length) { + buffer_insert(m_in, m_position, input, length); + if (m_position + length >= m_in.size()) { + encode_and_send(m_in.data(), m_in.size()); + input += (m_in.size() - m_position); + length -= (m_in.size() - m_position); + while (length >= m_in.size()) { + encode_and_send(input, m_in.size()); + input += m_in.size(); + length -= m_in.size(); + } + copy_mem(m_in.data(), input, length); + m_position = 0; + } + m_position += length; +} + +/* + * Flush buffers + */ +void Hex_Encoder::end_msg() { + encode_and_send(m_in.data(), m_position); + if (m_counter && m_line_length) send('\n'); + m_counter = m_position = 0; +} + +/* + * Hex_Decoder Constructor + */ +Hex_Decoder::Hex_Decoder(Decoder_Checking c) : m_checking(c) { + m_in.resize(HEX_CODEC_BUFFER_SIZE); + m_out.resize(m_in.size() / 2); + m_position = 0; +} + +/* + * Convert some data from hex format + */ +void Hex_Decoder::write(const uint8_t input[], size_t length) { + while (length) { + size_t to_copy = std::min(length, m_in.size() - m_position); + copy_mem(&m_in[m_position], input, to_copy); + m_position += to_copy; + + size_t consumed = 0; + size_t written = hex_decode(m_out.data(), cast_uint8_ptr_to_char(m_in.data()), m_position, + consumed, m_checking != FULL_CHECK); + + send(m_out, written); + + if (consumed != m_position) { + copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed); + m_position = m_position - consumed; + } else + m_position = 0; + + length -= to_copy; + input += to_copy; + } +} + +/* + * Flush buffers + */ +void Hex_Decoder::end_msg() { + size_t consumed = 0; + size_t written = hex_decode(m_out.data(), cast_uint8_ptr_to_char(m_in.data()), m_position, + consumed, m_checking != FULL_CHECK); + + send(m_out, written); + + const bool not_full_bytes = consumed != m_position; + + m_position = 0; + + if (not_full_bytes) throw Invalid_Argument("Hex_Decoder: Input not full bytes"); +} + +} // namespace Botan +/* + * Pipe Output Buffer + * (C) 1999-2007,2011 Jack Lloyd + * 2012 Markus Wanner + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Read data from a message -*/ -size_t Output_Buffers::read(uint8_t output[], size_t length, - Pipe::message_id msg) - { - SecureQueue* q = get(msg); - if(q) - return q->read(output, length); - return 0; - } - -/* -* Peek at data in a message -*/ -size_t Output_Buffers::peek(uint8_t output[], size_t length, - size_t stream_offset, - Pipe::message_id msg) const - { - SecureQueue* q = get(msg); - if(q) - return q->peek(output, length, stream_offset); - return 0; - } - -/* -* Check available bytes in a message -*/ -size_t Output_Buffers::remaining(Pipe::message_id msg) const - { - SecureQueue* q = get(msg); - if(q) - return q->size(); - return 0; - } - -/* -* Return the total bytes of a message that have already been read. -*/ -size_t Output_Buffers::get_bytes_read(Pipe::message_id msg) const - { - SecureQueue* q = get(msg); - if (q) - return q->get_bytes_read(); - return 0; - } - -/* -* Add a new output queue -*/ -void Output_Buffers::add(SecureQueue* queue) - { - BOTAN_ASSERT(queue, "queue was provided"); - - BOTAN_ASSERT(m_buffers.size() < m_buffers.max_size(), - "Room was available in container"); - - m_buffers.push_back(std::unique_ptr(queue)); - } - -/* -* Retire old output queues -*/ -void Output_Buffers::retire() - { - for(size_t i = 0; i != m_buffers.size(); ++i) - if(m_buffers[i] && m_buffers[i]->size() == 0) - { - m_buffers[i].reset(); - } - - while(m_buffers.size() && !m_buffers[0]) - { - m_buffers.pop_front(); - m_offset = m_offset + Pipe::message_id(1); - } - } - -/* -* Get a particular output queue -*/ -SecureQueue* Output_Buffers::get(Pipe::message_id msg) const - { - if(msg < m_offset) - return nullptr; - - BOTAN_ASSERT(msg < message_count(), "Message number is in range"); - - return m_buffers[msg-m_offset].get(); - } - -/* -* Return the total number of messages -*/ -Pipe::message_id Output_Buffers::message_count() const - { - return (m_offset + m_buffers.size()); - } - -/* -* Output_Buffers Constructor -*/ -Output_Buffers::Output_Buffers() - { - m_offset = 0; - } - + * Read data from a message + */ +size_t Output_Buffers::read(uint8_t output[], size_t length, Pipe::message_id msg) { + SecureQueue* q = get(msg); + if (q) return q->read(output, length); + return 0; } -/* -* Pipe -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Peek at data in a message + */ +size_t Output_Buffers::peek(uint8_t output[], size_t length, size_t stream_offset, + Pipe::message_id msg) const { + SecureQueue* q = get(msg); + if (q) return q->peek(output, length, stream_offset); + return 0; +} + +/* + * Check available bytes in a message + */ +size_t Output_Buffers::remaining(Pipe::message_id msg) const { + SecureQueue* q = get(msg); + if (q) return q->size(); + return 0; +} + +/* + * Return the total bytes of a message that have already been read. + */ +size_t Output_Buffers::get_bytes_read(Pipe::message_id msg) const { + SecureQueue* q = get(msg); + if (q) return q->get_bytes_read(); + return 0; +} + +/* + * Add a new output queue + */ +void Output_Buffers::add(SecureQueue* queue) { + BOTAN_ASSERT(queue, "queue was provided"); + + BOTAN_ASSERT(m_buffers.size() < m_buffers.max_size(), "Room was available in container"); + + m_buffers.push_back(std::unique_ptr(queue)); +} + +/* + * Retire old output queues + */ +void Output_Buffers::retire() { + for (size_t i = 0; i != m_buffers.size(); ++i) + if (m_buffers[i] && m_buffers[i]->size() == 0) { + m_buffers[i].reset(); + } + + while (m_buffers.size() && !m_buffers[0]) { + m_buffers.pop_front(); + m_offset = m_offset + Pipe::message_id(1); + } +} + +/* + * Get a particular output queue + */ +SecureQueue* Output_Buffers::get(Pipe::message_id msg) const { + if (msg < m_offset) return nullptr; + + BOTAN_ASSERT(msg < message_count(), "Message number is in range"); + + return m_buffers[msg - m_offset].get(); +} + +/* + * Return the total number of messages + */ +Pipe::message_id Output_Buffers::message_count() const { return (m_offset + m_buffers.size()); } + +/* + * Output_Buffers Constructor + */ +Output_Buffers::Output_Buffers() { m_offset = 0; } + +} // namespace Botan +/* + * Pipe + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { /* -* A Filter that does nothing -*/ -class Null_Filter final : public Filter - { + * A Filter that does nothing + */ +class Null_Filter final : public Filter { public: - void write(const uint8_t input[], size_t length) override - { send(input, length); } + void write(const uint8_t input[], size_t length) override { send(input, length); } - std::string name() const override { return "Null"; } - }; + std::string name() const override { return "Null"; } +}; +} // namespace + +/* + * Pipe Constructor + */ +Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) : Pipe({f1, f2, f3, f4}) {} + +/* + * Pipe Constructor + */ +Pipe::Pipe(std::initializer_list args) { + m_outputs.reset(new Output_Buffers); + m_pipe = nullptr; + m_default_read = 0; + m_inside_msg = false; + + for (auto i = args.begin(); i != args.end(); ++i) do_append(*i); } /* -* Pipe Constructor -*/ -Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) : - Pipe({f1,f2,f3,f4}) - { - } + * Pipe Destructor + */ +Pipe::~Pipe() { destruct(m_pipe); } /* -* Pipe Constructor -*/ -Pipe::Pipe(std::initializer_list args) - { - m_outputs.reset(new Output_Buffers); - m_pipe = nullptr; - m_default_read = 0; - m_inside_msg = false; - - for(auto i = args.begin(); i != args.end(); ++i) - do_append(*i); - } - -/* -* Pipe Destructor -*/ -Pipe::~Pipe() - { - destruct(m_pipe); - } - -/* -* Reset the Pipe -*/ -void Pipe::reset() - { - destruct(m_pipe); - m_pipe = nullptr; - m_inside_msg = false; - } - -/* -* Destroy the Pipe -*/ -void Pipe::destruct(Filter* to_kill) - { - if(!to_kill || dynamic_cast(to_kill)) - return; - for(size_t j = 0; j != to_kill->total_ports(); ++j) - destruct(to_kill->m_next[j]); - delete to_kill; - } - -/* -* Test if the Pipe has any data in it -*/ -bool Pipe::end_of_data() const - { - return (remaining() == 0); - } - -/* -* Set the default read message -*/ -void Pipe::set_default_msg(message_id msg) - { - if(msg >= message_count()) - throw Invalid_Argument("Pipe::set_default_msg: msg number is too high"); - m_default_read = msg; - } - -/* -* Process a full message at once -*/ -void Pipe::process_msg(const uint8_t input[], size_t length) - { - start_msg(); - write(input, length); - end_msg(); - } - -/* -* Process a full message at once -*/ -void Pipe::process_msg(const secure_vector& input) - { - process_msg(input.data(), input.size()); - } - -void Pipe::process_msg(const std::vector& input) - { - process_msg(input.data(), input.size()); - } - -/* -* Process a full message at once -*/ -void Pipe::process_msg(const std::string& input) - { - process_msg(cast_char_ptr_to_uint8(input.data()), input.length()); - } - -/* -* Process a full message at once -*/ -void Pipe::process_msg(DataSource& input) - { - start_msg(); - write(input); - end_msg(); - } - -/* -* Start a new message -*/ -void Pipe::start_msg() - { - if(m_inside_msg) - throw Invalid_State("Pipe::start_msg: Message was already started"); - if(m_pipe == nullptr) - m_pipe = new Null_Filter; - find_endpoints(m_pipe); - m_pipe->new_msg(); - m_inside_msg = true; - } - -/* -* End the current message -*/ -void Pipe::end_msg() - { - if(!m_inside_msg) - throw Invalid_State("Pipe::end_msg: Message was already ended"); - m_pipe->finish_msg(); - clear_endpoints(m_pipe); - if(dynamic_cast(m_pipe)) - { - delete m_pipe; - m_pipe = nullptr; - } - m_inside_msg = false; - - m_outputs->retire(); - } - -/* -* Find the endpoints of the Pipe -*/ -void Pipe::find_endpoints(Filter* f) - { - for(size_t j = 0; j != f->total_ports(); ++j) - if(f->m_next[j] && !dynamic_cast(f->m_next[j])) - find_endpoints(f->m_next[j]); - else - { - SecureQueue* q = new SecureQueue; - f->m_next[j] = q; - m_outputs->add(q); - } - } - -/* -* Remove the SecureQueues attached to the Filter -*/ -void Pipe::clear_endpoints(Filter* f) - { - if(!f) return; - for(size_t j = 0; j != f->total_ports(); ++j) - { - if(f->m_next[j] && dynamic_cast(f->m_next[j])) - f->m_next[j] = nullptr; - clear_endpoints(f->m_next[j]); - } - } - -void Pipe::append(Filter* filter) - { - do_append(filter); - } - -void Pipe::append_filter(Filter* filter) - { - if(m_outputs->message_count() != 0) - throw Invalid_State("Cannot call Pipe::append_filter after start_msg"); - - do_append(filter); - } - -void Pipe::prepend(Filter* filter) - { - do_prepend(filter); - } - -void Pipe::prepend_filter(Filter* filter) - { - if(m_outputs->message_count() != 0) - throw Invalid_State("Cannot call Pipe::prepend_filter after start_msg"); - - do_prepend(filter); - } - -/* -* Append a Filter to the Pipe -*/ -void Pipe::do_append(Filter* filter) - { - if(!filter) - return; - if(dynamic_cast(filter)) - throw Invalid_Argument("Pipe::append: SecureQueue cannot be used"); - if(filter->m_owned) - throw Invalid_Argument("Filters cannot be shared among multiple Pipes"); - - if(m_inside_msg) - throw Invalid_State("Cannot append to a Pipe while it is processing"); - - filter->m_owned = true; - - if(!m_pipe) m_pipe = filter; - else m_pipe->attach(filter); - } - -/* -* Prepend a Filter to the Pipe -*/ -void Pipe::do_prepend(Filter* filter) - { - if(m_inside_msg) - throw Invalid_State("Cannot prepend to a Pipe while it is processing"); - if(!filter) - return; - if(dynamic_cast(filter)) - throw Invalid_Argument("Pipe::prepend: SecureQueue cannot be used"); - if(filter->m_owned) - throw Invalid_Argument("Filters cannot be shared among multiple Pipes"); - - filter->m_owned = true; - - if(m_pipe) filter->attach(m_pipe); - m_pipe = filter; - } - -/* -* Pop a Filter off the Pipe -*/ -void Pipe::pop() - { - if(m_inside_msg) - throw Invalid_State("Cannot pop off a Pipe while it is processing"); - - if(!m_pipe) - return; - - if(m_pipe->total_ports() > 1) - throw Invalid_State("Cannot pop off a Filter with multiple ports"); - - size_t to_remove = m_pipe->owns() + 1; - - while(to_remove--) - { - std::unique_ptr to_destroy(m_pipe); - m_pipe = m_pipe->m_next[0]; - } - } - -/* -* Return the number of messages in this Pipe -*/ -Pipe::message_id Pipe::message_count() const - { - return m_outputs->message_count(); - } - -/* -* Static Member Variables -*/ -const Pipe::message_id Pipe::LAST_MESSAGE = - static_cast(-2); - -const Pipe::message_id Pipe::DEFAULT_MESSAGE = - static_cast(-1); - + * Reset the Pipe + */ +void Pipe::reset() { + destruct(m_pipe); + m_pipe = nullptr; + m_inside_msg = false; } -/* -* Pipe I/O -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Destroy the Pipe + */ +void Pipe::destruct(Filter* to_kill) { + if (!to_kill || dynamic_cast(to_kill)) return; + for (size_t j = 0; j != to_kill->total_ports(); ++j) destruct(to_kill->m_next[j]); + delete to_kill; +} + +/* + * Test if the Pipe has any data in it + */ +bool Pipe::end_of_data() const { return (remaining() == 0); } + +/* + * Set the default read message + */ +void Pipe::set_default_msg(message_id msg) { + if (msg >= message_count()) + throw Invalid_Argument("Pipe::set_default_msg: msg number is too high"); + m_default_read = msg; +} + +/* + * Process a full message at once + */ +void Pipe::process_msg(const uint8_t input[], size_t length) { + start_msg(); + write(input, length); + end_msg(); +} + +/* + * Process a full message at once + */ +void Pipe::process_msg(const secure_vector& input) { + process_msg(input.data(), input.size()); +} + +void Pipe::process_msg(const std::vector& input) { + process_msg(input.data(), input.size()); +} + +/* + * Process a full message at once + */ +void Pipe::process_msg(const std::string& input) { + process_msg(cast_char_ptr_to_uint8(input.data()), input.length()); +} + +/* + * Process a full message at once + */ +void Pipe::process_msg(DataSource& input) { + start_msg(); + write(input); + end_msg(); +} + +/* + * Start a new message + */ +void Pipe::start_msg() { + if (m_inside_msg) throw Invalid_State("Pipe::start_msg: Message was already started"); + if (m_pipe == nullptr) m_pipe = new Null_Filter; + find_endpoints(m_pipe); + m_pipe->new_msg(); + m_inside_msg = true; +} + +/* + * End the current message + */ +void Pipe::end_msg() { + if (!m_inside_msg) throw Invalid_State("Pipe::end_msg: Message was already ended"); + m_pipe->finish_msg(); + clear_endpoints(m_pipe); + if (dynamic_cast(m_pipe)) { + delete m_pipe; + m_pipe = nullptr; + } + m_inside_msg = false; + + m_outputs->retire(); +} + +/* + * Find the endpoints of the Pipe + */ +void Pipe::find_endpoints(Filter* f) { + for (size_t j = 0; j != f->total_ports(); ++j) + if (f->m_next[j] && !dynamic_cast(f->m_next[j])) + find_endpoints(f->m_next[j]); + else { + SecureQueue* q = new SecureQueue; + f->m_next[j] = q; + m_outputs->add(q); + } +} + +/* + * Remove the SecureQueues attached to the Filter + */ +void Pipe::clear_endpoints(Filter* f) { + if (!f) return; + for (size_t j = 0; j != f->total_ports(); ++j) { + if (f->m_next[j] && dynamic_cast(f->m_next[j])) f->m_next[j] = nullptr; + clear_endpoints(f->m_next[j]); + } +} + +void Pipe::append(Filter* filter) { do_append(filter); } + +void Pipe::append_filter(Filter* filter) { + if (m_outputs->message_count() != 0) + throw Invalid_State("Cannot call Pipe::append_filter after start_msg"); + + do_append(filter); +} + +void Pipe::prepend(Filter* filter) { do_prepend(filter); } + +void Pipe::prepend_filter(Filter* filter) { + if (m_outputs->message_count() != 0) + throw Invalid_State("Cannot call Pipe::prepend_filter after start_msg"); + + do_prepend(filter); +} + +/* + * Append a Filter to the Pipe + */ +void Pipe::do_append(Filter* filter) { + if (!filter) return; + if (dynamic_cast(filter)) + throw Invalid_Argument("Pipe::append: SecureQueue cannot be used"); + if (filter->m_owned) throw Invalid_Argument("Filters cannot be shared among multiple Pipes"); + + if (m_inside_msg) throw Invalid_State("Cannot append to a Pipe while it is processing"); + + filter->m_owned = true; + + if (!m_pipe) + m_pipe = filter; + else + m_pipe->attach(filter); +} + +/* + * Prepend a Filter to the Pipe + */ +void Pipe::do_prepend(Filter* filter) { + if (m_inside_msg) throw Invalid_State("Cannot prepend to a Pipe while it is processing"); + if (!filter) return; + if (dynamic_cast(filter)) + throw Invalid_Argument("Pipe::prepend: SecureQueue cannot be used"); + if (filter->m_owned) throw Invalid_Argument("Filters cannot be shared among multiple Pipes"); + + filter->m_owned = true; + + if (m_pipe) filter->attach(m_pipe); + m_pipe = filter; +} + +/* + * Pop a Filter off the Pipe + */ +void Pipe::pop() { + if (m_inside_msg) throw Invalid_State("Cannot pop off a Pipe while it is processing"); + + if (!m_pipe) return; + + if (m_pipe->total_ports() > 1) + throw Invalid_State("Cannot pop off a Filter with multiple ports"); + + size_t to_remove = m_pipe->owns() + 1; + + while (to_remove--) { + std::unique_ptr to_destroy(m_pipe); + m_pipe = m_pipe->m_next[0]; + } +} + +/* + * Return the number of messages in this Pipe + */ +Pipe::message_id Pipe::message_count() const { return m_outputs->message_count(); } + +/* + * Static Member Variables + */ +const Pipe::message_id Pipe::LAST_MESSAGE = static_cast(-2); + +const Pipe::message_id Pipe::DEFAULT_MESSAGE = static_cast(-1); + +} // namespace Botan +/* + * Pipe I/O + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Write data from a pipe into an ostream -*/ -std::ostream& operator<<(std::ostream& stream, Pipe& pipe) - { - secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); - while(stream.good() && pipe.remaining()) - { - const size_t got = pipe.read(buffer.data(), buffer.size()); - stream.write(cast_uint8_ptr_to_char(buffer.data()), got); - } - if(!stream.good()) - throw Stream_IO_Error("Pipe output operator (iostream) has failed"); - return stream; - } - -/* -* Read data from an istream into a pipe -*/ -std::istream& operator>>(std::istream& stream, Pipe& pipe) - { - secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); - while(stream.good()) - { - stream.read(cast_uint8_ptr_to_char(buffer.data()), buffer.size()); - const size_t got = static_cast(stream.gcount()); - pipe.write(buffer.data(), got); - } - if(stream.bad() || (stream.fail() && !stream.eof())) - throw Stream_IO_Error("Pipe input operator (iostream) has failed"); - return stream; - } - + * Write data from a pipe into an ostream + */ +std::ostream& operator<<(std::ostream& stream, Pipe& pipe) { + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); + while (stream.good() && pipe.remaining()) { + const size_t got = pipe.read(buffer.data(), buffer.size()); + stream.write(cast_uint8_ptr_to_char(buffer.data()), got); + } + if (!stream.good()) throw Stream_IO_Error("Pipe output operator (iostream) has failed"); + return stream; } -/* -* Pipe Reading/Writing -* (C) 1999-2007 Jack Lloyd -* 2012 Markus Wanner -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Read data from an istream into a pipe + */ +std::istream& operator>>(std::istream& stream, Pipe& pipe) { + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); + while (stream.good()) { + stream.read(cast_uint8_ptr_to_char(buffer.data()), buffer.size()); + const size_t got = static_cast(stream.gcount()); + pipe.write(buffer.data(), got); + } + if (stream.bad() || (stream.fail() && !stream.eof())) + throw Stream_IO_Error("Pipe input operator (iostream) has failed"); + return stream; +} + +} // namespace Botan +/* + * Pipe Reading/Writing + * (C) 1999-2007 Jack Lloyd + * 2012 Markus Wanner + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Look up the canonical ID for a queue -*/ -Pipe::message_id Pipe::get_message_no(const std::string& func_name, - message_id msg) const - { - if(msg == DEFAULT_MESSAGE) - msg = default_msg(); - else if(msg == LAST_MESSAGE) - msg = message_count() - 1; + * Look up the canonical ID for a queue + */ +Pipe::message_id Pipe::get_message_no(const std::string& func_name, message_id msg) const { + if (msg == DEFAULT_MESSAGE) + msg = default_msg(); + else if (msg == LAST_MESSAGE) + msg = message_count() - 1; - if(msg >= message_count()) - throw Invalid_Message_Number(func_name, msg); - - return msg; - } - -/* -* Write into a Pipe -*/ -void Pipe::write(const uint8_t input[], size_t length) - { - if(!m_inside_msg) - throw Invalid_State("Cannot write to a Pipe while it is not processing"); - m_pipe->write(input, length); - } - -/* -* Write a string into a Pipe -*/ -void Pipe::write(const std::string& str) - { - write(cast_char_ptr_to_uint8(str.data()), str.size()); - } - -/* -* Write a single byte into a Pipe -*/ -void Pipe::write(uint8_t input) - { - write(&input, 1); - } - -/* -* Write the contents of a DataSource into a Pipe -*/ -void Pipe::write(DataSource& source) - { - secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); - while(!source.end_of_data()) - { - size_t got = source.read(buffer.data(), buffer.size()); - write(buffer.data(), got); - } - } - -/* -* Read some data from the pipe -*/ -size_t Pipe::read(uint8_t output[], size_t length, message_id msg) - { - return m_outputs->read(output, length, get_message_no("read", msg)); - } - -/* -* Read some data from the pipe -*/ -size_t Pipe::read(uint8_t output[], size_t length) - { - return read(output, length, DEFAULT_MESSAGE); - } - -/* -* Read a single byte from the pipe -*/ -size_t Pipe::read(uint8_t& out, message_id msg) - { - return read(&out, 1, msg); - } - -/* -* Return all data in the pipe -*/ -secure_vector Pipe::read_all(message_id msg) - { - msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg()); - secure_vector buffer(remaining(msg)); - size_t got = read(buffer.data(), buffer.size(), msg); - buffer.resize(got); - return buffer; - } - -/* -* Return all data in the pipe as a string -*/ -std::string Pipe::read_all_as_string(message_id msg) - { - msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg()); - secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); - std::string str; - str.reserve(remaining(msg)); - - while(true) - { - size_t got = read(buffer.data(), buffer.size(), msg); - if(got == 0) - break; - str.append(cast_uint8_ptr_to_char(buffer.data()), got); - } - - return str; - } - -/* -* Find out how many bytes are ready to read -*/ -size_t Pipe::remaining(message_id msg) const - { - return m_outputs->remaining(get_message_no("remaining", msg)); - } - -/* -* Peek at some data in the pipe -*/ -size_t Pipe::peek(uint8_t output[], size_t length, - size_t offset, message_id msg) const - { - return m_outputs->peek(output, length, offset, get_message_no("peek", msg)); - } - -/* -* Peek at some data in the pipe -*/ -size_t Pipe::peek(uint8_t output[], size_t length, size_t offset) const - { - return peek(output, length, offset, DEFAULT_MESSAGE); - } - -/* -* Peek at a byte in the pipe -*/ -size_t Pipe::peek(uint8_t& out, size_t offset, message_id msg) const - { - return peek(&out, 1, offset, msg); - } - -size_t Pipe::get_bytes_read() const - { - return m_outputs->get_bytes_read(default_msg()); - } - -size_t Pipe::get_bytes_read(message_id msg) const - { - return m_outputs->get_bytes_read(msg); - } - -bool Pipe::check_available(size_t n) - { - return (n <= remaining(default_msg())); - } - -bool Pipe::check_available_msg(size_t n, message_id msg) - { - return (n <= remaining(msg)); - } + if (msg >= message_count()) throw Invalid_Message_Number(func_name, msg); + return msg; } -/* -* SecureQueue -* (C) 1999-2007 Jack Lloyd -* 2012 Markus Wanner -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Write into a Pipe + */ +void Pipe::write(const uint8_t input[], size_t length) { + if (!m_inside_msg) throw Invalid_State("Cannot write to a Pipe while it is not processing"); + m_pipe->write(input, length); +} + +/* + * Write a string into a Pipe + */ +void Pipe::write(const std::string& str) { write(cast_char_ptr_to_uint8(str.data()), str.size()); } + +/* + * Write a single byte into a Pipe + */ +void Pipe::write(uint8_t input) { write(&input, 1); } + +/* + * Write the contents of a DataSource into a Pipe + */ +void Pipe::write(DataSource& source) { + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); + while (!source.end_of_data()) { + size_t got = source.read(buffer.data(), buffer.size()); + write(buffer.data(), got); + } +} + +/* + * Read some data from the pipe + */ +size_t Pipe::read(uint8_t output[], size_t length, message_id msg) { + return m_outputs->read(output, length, get_message_no("read", msg)); +} + +/* + * Read some data from the pipe + */ +size_t Pipe::read(uint8_t output[], size_t length) { return read(output, length, DEFAULT_MESSAGE); } + +/* + * Read a single byte from the pipe + */ +size_t Pipe::read(uint8_t& out, message_id msg) { return read(&out, 1, msg); } + +/* + * Return all data in the pipe + */ +secure_vector Pipe::read_all(message_id msg) { + msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg()); + secure_vector buffer(remaining(msg)); + size_t got = read(buffer.data(), buffer.size(), msg); + buffer.resize(got); + return buffer; +} + +/* + * Return all data in the pipe as a string + */ +std::string Pipe::read_all_as_string(message_id msg) { + msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg()); + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); + std::string str; + str.reserve(remaining(msg)); + + while (true) { + size_t got = read(buffer.data(), buffer.size(), msg); + if (got == 0) break; + str.append(cast_uint8_ptr_to_char(buffer.data()), got); + } + + return str; +} + +/* + * Find out how many bytes are ready to read + */ +size_t Pipe::remaining(message_id msg) const { + return m_outputs->remaining(get_message_no("remaining", msg)); +} + +/* + * Peek at some data in the pipe + */ +size_t Pipe::peek(uint8_t output[], size_t length, size_t offset, message_id msg) const { + return m_outputs->peek(output, length, offset, get_message_no("peek", msg)); +} + +/* + * Peek at some data in the pipe + */ +size_t Pipe::peek(uint8_t output[], size_t length, size_t offset) const { + return peek(output, length, offset, DEFAULT_MESSAGE); +} + +/* + * Peek at a byte in the pipe + */ +size_t Pipe::peek(uint8_t& out, size_t offset, message_id msg) const { + return peek(&out, 1, offset, msg); +} + +size_t Pipe::get_bytes_read() const { return m_outputs->get_bytes_read(default_msg()); } + +size_t Pipe::get_bytes_read(message_id msg) const { return m_outputs->get_bytes_read(msg); } + +bool Pipe::check_available(size_t n) { return (n <= remaining(default_msg())); } + +bool Pipe::check_available_msg(size_t n, message_id msg) { return (n <= remaining(msg)); } + +} // namespace Botan +/* + * SecureQueue + * (C) 1999-2007 Jack Lloyd + * 2012 Markus Wanner + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /** -* A node in a SecureQueue -*/ -class SecureQueueNode final - { + * A node in a SecureQueue + */ +class SecureQueueNode final { public: - SecureQueueNode() : m_buffer(BOTAN_DEFAULT_BUFFER_SIZE) - { m_next = nullptr; m_start = m_end = 0; } + SecureQueueNode() : m_buffer(BOTAN_DEFAULT_BUFFER_SIZE) { + m_next = nullptr; + m_start = m_end = 0; + } - ~SecureQueueNode() { m_next = nullptr; m_start = m_end = 0; } + ~SecureQueueNode() { + m_next = nullptr; + m_start = m_end = 0; + } - size_t write(const uint8_t input[], size_t length) - { - size_t copied = std::min(length, m_buffer.size() - m_end); - copy_mem(m_buffer.data() + m_end, input, copied); - m_end += copied; - return copied; - } + size_t write(const uint8_t input[], size_t length) { + size_t copied = std::min(length, m_buffer.size() - m_end); + copy_mem(m_buffer.data() + m_end, input, copied); + m_end += copied; + return copied; + } - size_t read(uint8_t output[], size_t length) - { - size_t copied = std::min(length, m_end - m_start); - copy_mem(output, m_buffer.data() + m_start, copied); - m_start += copied; - return copied; - } + size_t read(uint8_t output[], size_t length) { + size_t copied = std::min(length, m_end - m_start); + copy_mem(output, m_buffer.data() + m_start, copied); + m_start += copied; + return copied; + } - size_t peek(uint8_t output[], size_t length, size_t offset = 0) - { - const size_t left = m_end - m_start; - if(offset >= left) return 0; - size_t copied = std::min(length, left - offset); - copy_mem(output, m_buffer.data() + m_start + offset, copied); - return copied; - } + size_t peek(uint8_t output[], size_t length, size_t offset = 0) { + const size_t left = m_end - m_start; + if (offset >= left) return 0; + size_t copied = std::min(length, left - offset); + copy_mem(output, m_buffer.data() + m_start + offset, copied); + return copied; + } + + size_t size() const { return (m_end - m_start); } - size_t size() const { return (m_end - m_start); } private: - friend class SecureQueue; - SecureQueueNode* m_next; - secure_vector m_buffer; - size_t m_start, m_end; - }; + friend class SecureQueue; + SecureQueueNode* m_next; + secure_vector m_buffer; + size_t m_start, m_end; +}; /* -* Create a SecureQueue -*/ -SecureQueue::SecureQueue() - { - m_bytes_read = 0; - set_next(nullptr, 0); - m_head = m_tail = new SecureQueueNode; - } + * Create a SecureQueue + */ +SecureQueue::SecureQueue() { + m_bytes_read = 0; + set_next(nullptr, 0); + m_head = m_tail = new SecureQueueNode; +} /* -* Copy a SecureQueue -*/ -SecureQueue::SecureQueue(const SecureQueue& input) : - Fanout_Filter(), DataSource() - { - m_bytes_read = 0; - set_next(nullptr, 0); + * Copy a SecureQueue + */ +SecureQueue::SecureQueue(const SecureQueue& input) : Fanout_Filter(), DataSource() { + m_bytes_read = 0; + set_next(nullptr, 0); - m_head = m_tail = new SecureQueueNode; - SecureQueueNode* temp = input.m_head; - while(temp) - { - write(&temp->m_buffer[temp->m_start], temp->m_end - temp->m_start); - temp = temp->m_next; - } - } + m_head = m_tail = new SecureQueueNode; + SecureQueueNode* temp = input.m_head; + while (temp) { + write(&temp->m_buffer[temp->m_start], temp->m_end - temp->m_start); + temp = temp->m_next; + } +} /* -* Destroy this SecureQueue -*/ -void SecureQueue::destroy() - { - SecureQueueNode* temp = m_head; - while(temp) - { - SecureQueueNode* holder = temp->m_next; - delete temp; - temp = holder; - } - m_head = m_tail = nullptr; - } + * Destroy this SecureQueue + */ +void SecureQueue::destroy() { + SecureQueueNode* temp = m_head; + while (temp) { + SecureQueueNode* holder = temp->m_next; + delete temp; + temp = holder; + } + m_head = m_tail = nullptr; +} /* -* Copy a SecureQueue -*/ -SecureQueue& SecureQueue::operator=(const SecureQueue& input) - { - if(this == &input) - return *this; + * Copy a SecureQueue + */ +SecureQueue& SecureQueue::operator=(const SecureQueue& input) { + if (this == &input) return *this; - destroy(); - m_bytes_read = input.get_bytes_read(); - m_head = m_tail = new SecureQueueNode; - SecureQueueNode* temp = input.m_head; - while(temp) - { - write(&temp->m_buffer[temp->m_start], temp->m_end - temp->m_start); - temp = temp->m_next; - } - return (*this); - } + destroy(); + m_bytes_read = input.get_bytes_read(); + m_head = m_tail = new SecureQueueNode; + SecureQueueNode* temp = input.m_head; + while (temp) { + write(&temp->m_buffer[temp->m_start], temp->m_end - temp->m_start); + temp = temp->m_next; + } + return (*this); +} /* -* Add some bytes to the queue -*/ -void SecureQueue::write(const uint8_t input[], size_t length) - { - if(!m_head) - m_head = m_tail = new SecureQueueNode; - while(length) - { - const size_t n = m_tail->write(input, length); - input += n; - length -= n; - if(length) - { - m_tail->m_next = new SecureQueueNode; - m_tail = m_tail->m_next; - } - } - } + * Add some bytes to the queue + */ +void SecureQueue::write(const uint8_t input[], size_t length) { + if (!m_head) m_head = m_tail = new SecureQueueNode; + while (length) { + const size_t n = m_tail->write(input, length); + input += n; + length -= n; + if (length) { + m_tail->m_next = new SecureQueueNode; + m_tail = m_tail->m_next; + } + } +} /* -* Read some bytes from the queue -*/ -size_t SecureQueue::read(uint8_t output[], size_t length) - { - size_t got = 0; - while(length && m_head) - { - const size_t n = m_head->read(output, length); - output += n; - got += n; - length -= n; - if(m_head->size() == 0) - { - SecureQueueNode* holder = m_head->m_next; - delete m_head; - m_head = holder; - } - } - m_bytes_read += got; - return got; - } + * Read some bytes from the queue + */ +size_t SecureQueue::read(uint8_t output[], size_t length) { + size_t got = 0; + while (length && m_head) { + const size_t n = m_head->read(output, length); + output += n; + got += n; + length -= n; + if (m_head->size() == 0) { + SecureQueueNode* holder = m_head->m_next; + delete m_head; + m_head = holder; + } + } + m_bytes_read += got; + return got; +} /* -* Read data, but do not remove it from queue -*/ -size_t SecureQueue::peek(uint8_t output[], size_t length, size_t offset) const - { - SecureQueueNode* current = m_head; + * Read data, but do not remove it from queue + */ +size_t SecureQueue::peek(uint8_t output[], size_t length, size_t offset) const { + SecureQueueNode* current = m_head; - while(offset && current) - { - if(offset >= current->size()) - { - offset -= current->size(); - current = current->m_next; - } - else - break; - } + while (offset && current) { + if (offset >= current->size()) { + offset -= current->size(); + current = current->m_next; + } else + break; + } - size_t got = 0; - while(length && current) - { - const size_t n = current->peek(output, length, offset); - offset = 0; - output += n; - got += n; - length -= n; - current = current->m_next; - } - return got; - } + size_t got = 0; + while (length && current) { + const size_t n = current->peek(output, length, offset); + offset = 0; + output += n; + got += n; + length -= n; + current = current->m_next; + } + return got; +} /** -* Return how many bytes have been read so far. -*/ -size_t SecureQueue::get_bytes_read() const - { - return m_bytes_read; - } + * Return how many bytes have been read so far. + */ +size_t SecureQueue::get_bytes_read() const { return m_bytes_read; } /* -* Return how many bytes the queue holds -*/ -size_t SecureQueue::size() const - { - SecureQueueNode* current = m_head; - size_t count = 0; - - while(current) - { - count += current->size(); - current = current->m_next; - } - return count; - } - -/* -* Test if the queue has any data in it -*/ -bool SecureQueue::end_of_data() const - { - return (size() == 0); - } - -bool SecureQueue::empty() const - { - return (size() == 0); - } + * Return how many bytes the queue holds + */ +size_t SecureQueue::size() const { + SecureQueueNode* current = m_head; + size_t count = 0; + while (current) { + count += current->size(); + current = current->m_next; + } + return count; } -/* -* Threaded Fork -* (C) 2013 Joel Low -* 2013 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Test if the queue has any data in it + */ +bool SecureQueue::end_of_data() const { return (size() == 0); } + +bool SecureQueue::empty() const { return (size() == 0); } + +} // namespace Botan +/* + * Threaded Fork + * (C) 2013 Joel Low + * 2013 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_THREAD_UTILS) - namespace Botan { -struct Threaded_Fork_Data - { - /* - * Semaphore for indicating that there is work to be done (or to - * quit) - */ - Semaphore m_input_ready_semaphore; +struct Threaded_Fork_Data { + /* + * Semaphore for indicating that there is work to be done (or to + * quit) + */ + Semaphore m_input_ready_semaphore; - /* - * Synchronises all threads to complete processing data in lock-step. - */ - Barrier m_input_complete_barrier; + /* + * Synchronises all threads to complete processing data in lock-step. + */ + Barrier m_input_complete_barrier; - /* - * The work that needs to be done. This should be only when the threads - * are NOT running (i.e. before notifying the work condition, after - * the input_complete_barrier has reset.) - */ - const uint8_t* m_input = nullptr; + /* + * The work that needs to be done. This should be only when the threads + * are NOT running (i.e. before notifying the work condition, after + * the input_complete_barrier has reset.) + */ + const uint8_t* m_input = nullptr; - /* - * The length of the work that needs to be done. - */ - size_t m_input_length = 0; - }; + /* + * The length of the work that needs to be done. + */ + size_t m_input_length = 0; +}; /* -* Threaded_Fork constructor -*/ -Threaded_Fork::Threaded_Fork(Filter* f1, Filter* f2, Filter* f3, Filter* f4) : - Fork(nullptr, static_cast(0)), - m_thread_data(new Threaded_Fork_Data) - { - Filter* filters[4] = { f1, f2, f3, f4 }; - set_next(filters, 4); - } - -/* -* Threaded_Fork constructor -*/ -Threaded_Fork::Threaded_Fork(Filter* filters[], size_t count) : - Fork(nullptr, static_cast(0)), - m_thread_data(new Threaded_Fork_Data) - { - set_next(filters, count); - } - -Threaded_Fork::~Threaded_Fork() - { - m_thread_data->m_input = nullptr; - m_thread_data->m_input_length = 0; - - m_thread_data->m_input_ready_semaphore.release(m_threads.size()); - - for(auto& thread : m_threads) - thread->join(); - } - -std::string Threaded_Fork::name() const - { - return "Threaded Fork"; - } - -void Threaded_Fork::set_next(Filter* f[], size_t n) - { - Fork::set_next(f, n); - n = m_next.size(); - - if(n < m_threads.size()) - m_threads.resize(n); - else - { - m_threads.reserve(n); - for(size_t i = m_threads.size(); i != n; ++i) - { - m_threads.push_back( - std::shared_ptr( - new std::thread( - std::bind(&Threaded_Fork::thread_entry, this, m_next[i])))); - } - } - } - -void Threaded_Fork::send(const uint8_t input[], size_t length) - { - if(m_write_queue.size()) - thread_delegate_work(m_write_queue.data(), m_write_queue.size()); - thread_delegate_work(input, length); - - bool nothing_attached = true; - for(size_t j = 0; j != total_ports(); ++j) - if(m_next[j]) - nothing_attached = false; - - if(nothing_attached) - m_write_queue += std::make_pair(input, length); - else - m_write_queue.clear(); - } - -void Threaded_Fork::thread_delegate_work(const uint8_t input[], size_t length) - { - //Set the data to do. - m_thread_data->m_input = input; - m_thread_data->m_input_length = length; - - //Let the workers start processing. - m_thread_data->m_input_complete_barrier.wait(total_ports() + 1); - m_thread_data->m_input_ready_semaphore.release(total_ports()); - - //Wait for all the filters to finish processing. - m_thread_data->m_input_complete_barrier.sync(); - - //Reset the thread data - m_thread_data->m_input = nullptr; - m_thread_data->m_input_length = 0; - } - -void Threaded_Fork::thread_entry(Filter* filter) - { - while(true) - { - m_thread_data->m_input_ready_semaphore.acquire(); - - if(!m_thread_data->m_input) - break; - - filter->write(m_thread_data->m_input, m_thread_data->m_input_length); - m_thread_data->m_input_complete_barrier.sync(); - } - } - + * Threaded_Fork constructor + */ +Threaded_Fork::Threaded_Fork(Filter* f1, Filter* f2, Filter* f3, Filter* f4) + : Fork(nullptr, static_cast(0)), m_thread_data(new Threaded_Fork_Data) { + Filter* filters[4] = {f1, f2, f3, f4}; + set_next(filters, 4); } +/* + * Threaded_Fork constructor + */ +Threaded_Fork::Threaded_Fork(Filter* filters[], size_t count) + : Fork(nullptr, static_cast(0)), m_thread_data(new Threaded_Fork_Data) { + set_next(filters, count); +} + +Threaded_Fork::~Threaded_Fork() { + m_thread_data->m_input = nullptr; + m_thread_data->m_input_length = 0; + + m_thread_data->m_input_ready_semaphore.release(m_threads.size()); + + for (auto& thread : m_threads) thread->join(); +} + +std::string Threaded_Fork::name() const { return "Threaded Fork"; } + +void Threaded_Fork::set_next(Filter* f[], size_t n) { + Fork::set_next(f, n); + n = m_next.size(); + + if (n < m_threads.size()) + m_threads.resize(n); + else { + m_threads.reserve(n); + for (size_t i = m_threads.size(); i != n; ++i) { + m_threads.push_back(std::shared_ptr( + new std::thread(std::bind(&Threaded_Fork::thread_entry, this, m_next[i])))); + } + } +} + +void Threaded_Fork::send(const uint8_t input[], size_t length) { + if (m_write_queue.size()) thread_delegate_work(m_write_queue.data(), m_write_queue.size()); + thread_delegate_work(input, length); + + bool nothing_attached = true; + for (size_t j = 0; j != total_ports(); ++j) + if (m_next[j]) nothing_attached = false; + + if (nothing_attached) + m_write_queue += std::make_pair(input, length); + else + m_write_queue.clear(); +} + +void Threaded_Fork::thread_delegate_work(const uint8_t input[], size_t length) { + // Set the data to do. + m_thread_data->m_input = input; + m_thread_data->m_input_length = length; + + // Let the workers start processing. + m_thread_data->m_input_complete_barrier.wait(total_ports() + 1); + m_thread_data->m_input_ready_semaphore.release(total_ports()); + + // Wait for all the filters to finish processing. + m_thread_data->m_input_complete_barrier.sync(); + + // Reset the thread data + m_thread_data->m_input = nullptr; + m_thread_data->m_input_length = 0; +} + +void Threaded_Fork::thread_entry(Filter* filter) { + while (true) { + m_thread_data->m_input_ready_semaphore.acquire(); + + if (!m_thread_data->m_input) break; + + filter->write(m_thread_data->m_input, m_thread_data->m_input_length); + m_thread_data->m_input_complete_barrier.sync(); + } +} + +} // namespace Botan + #endif /* -* Hash Functions -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Hash Functions + * (C) 2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_ADLER32) #endif @@ -9877,934 +8312,745 @@ void Threaded_Fork::thread_entry(Filter* filter) namespace Botan { std::unique_ptr HashFunction::create(const std::string& algo_spec, - const std::string& provider) - { - + const std::string& provider) { #if defined(BOTAN_HAS_COMMONCRYPTO) - if(provider.empty() || provider == "commoncrypto") - { - if(auto hash = make_commoncrypto_hash(algo_spec)) - return hash; + if (provider.empty() || provider == "commoncrypto") { + if (auto hash = make_commoncrypto_hash(algo_spec)) return hash; - if(!provider.empty()) - return nullptr; - } + if (!provider.empty()) return nullptr; + } #endif #if defined(BOTAN_HAS_OPENSSL) - if(provider.empty() || provider == "openssl") - { - if(auto hash = make_openssl_hash(algo_spec)) - return hash; + if (provider.empty() || provider == "openssl") { + if (auto hash = make_openssl_hash(algo_spec)) return hash; - if(!provider.empty()) - return nullptr; - } + if (!provider.empty()) return nullptr; + } #endif - if(provider.empty() == false && provider != "base") - return nullptr; // unknown provider + if (provider.empty() == false && provider != "base") return nullptr; // unknown provider #if defined(BOTAN_HAS_SHA1) - if(algo_spec == "SHA-160" || - algo_spec == "SHA-1" || - algo_spec == "SHA1") - { - return std::unique_ptr(new SHA_160); - } + if (algo_spec == "SHA-160" || algo_spec == "SHA-1" || algo_spec == "SHA1") { + return std::unique_ptr(new SHA_160); + } #endif #if defined(BOTAN_HAS_SHA2_32) - if(algo_spec == "SHA-224") - { - return std::unique_ptr(new SHA_224); - } + if (algo_spec == "SHA-224") { + return std::unique_ptr(new SHA_224); + } - if(algo_spec == "SHA-256") - { - return std::unique_ptr(new SHA_256); - } + if (algo_spec == "SHA-256") { + return std::unique_ptr(new SHA_256); + } #endif #if defined(BOTAN_HAS_SHA2_64) - if(algo_spec == "SHA-384") - { - return std::unique_ptr(new SHA_384); - } + if (algo_spec == "SHA-384") { + return std::unique_ptr(new SHA_384); + } - if(algo_spec == "SHA-512") - { - return std::unique_ptr(new SHA_512); - } + if (algo_spec == "SHA-512") { + return std::unique_ptr(new SHA_512); + } - if(algo_spec == "SHA-512-256") - { - return std::unique_ptr(new SHA_512_256); - } + if (algo_spec == "SHA-512-256") { + return std::unique_ptr(new SHA_512_256); + } #endif #if defined(BOTAN_HAS_RIPEMD_160) - if(algo_spec == "RIPEMD-160") - { - return std::unique_ptr(new RIPEMD_160); - } + if (algo_spec == "RIPEMD-160") { + return std::unique_ptr(new RIPEMD_160); + } #endif #if defined(BOTAN_HAS_WHIRLPOOL) - if(algo_spec == "Whirlpool") - { - return std::unique_ptr(new Whirlpool); - } + if (algo_spec == "Whirlpool") { + return std::unique_ptr(new Whirlpool); + } #endif #if defined(BOTAN_HAS_MD5) - if(algo_spec == "MD5") - { - return std::unique_ptr(new MD5); - } + if (algo_spec == "MD5") { + return std::unique_ptr(new MD5); + } #endif #if defined(BOTAN_HAS_MD4) - if(algo_spec == "MD4") - { - return std::unique_ptr(new MD4); - } + if (algo_spec == "MD4") { + return std::unique_ptr(new MD4); + } #endif #if defined(BOTAN_HAS_GOST_34_11) - if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11") - { - return std::unique_ptr(new GOST_34_11); - } + if (algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11") { + return std::unique_ptr(new GOST_34_11); + } #endif #if defined(BOTAN_HAS_ADLER32) - if(algo_spec == "Adler32") - { - return std::unique_ptr(new Adler32); - } + if (algo_spec == "Adler32") { + return std::unique_ptr(new Adler32); + } #endif #if defined(BOTAN_HAS_CRC24) - if(algo_spec == "CRC24") - { - return std::unique_ptr(new CRC24); - } + if (algo_spec == "CRC24") { + return std::unique_ptr(new CRC24); + } #endif #if defined(BOTAN_HAS_CRC32) - if(algo_spec == "CRC32") - { - return std::unique_ptr(new CRC32); - } + if (algo_spec == "CRC32") { + return std::unique_ptr(new CRC32); + } #endif - const SCAN_Name req(algo_spec); + const SCAN_Name req(algo_spec); #if defined(BOTAN_HAS_TIGER) - if(req.algo_name() == "Tiger") - { - return std::unique_ptr( - new Tiger(req.arg_as_integer(0, 24), - req.arg_as_integer(1, 3))); - } + if (req.algo_name() == "Tiger") { + return std::unique_ptr( + new Tiger(req.arg_as_integer(0, 24), req.arg_as_integer(1, 3))); + } #endif #if defined(BOTAN_HAS_SKEIN_512) - if(req.algo_name() == "Skein-512") - { - return std::unique_ptr( - new Skein_512(req.arg_as_integer(0, 512), req.arg(1, ""))); - } + if (req.algo_name() == "Skein-512") { + return std::unique_ptr( + new Skein_512(req.arg_as_integer(0, 512), req.arg(1, ""))); + } #endif #if defined(BOTAN_HAS_BLAKE2B) - if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b") - { - return std::unique_ptr( - new Blake2b(req.arg_as_integer(0, 512))); - } + if (req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b") { + return std::unique_ptr(new Blake2b(req.arg_as_integer(0, 512))); + } #endif #if defined(BOTAN_HAS_KECCAK) - if(req.algo_name() == "Keccak-1600") - { - return std::unique_ptr( - new Keccak_1600(req.arg_as_integer(0, 512))); - } + if (req.algo_name() == "Keccak-1600") { + return std::unique_ptr(new Keccak_1600(req.arg_as_integer(0, 512))); + } #endif #if defined(BOTAN_HAS_SHA3) - if(req.algo_name() == "SHA-3") - { - return std::unique_ptr( - new SHA_3(req.arg_as_integer(0, 512))); - } + if (req.algo_name() == "SHA-3") { + return std::unique_ptr(new SHA_3(req.arg_as_integer(0, 512))); + } #endif #if defined(BOTAN_HAS_SHAKE) - if(req.algo_name() == "SHAKE-128") - { - return std::unique_ptr(new SHAKE_128(req.arg_as_integer(0, 128))); - } - if(req.algo_name() == "SHAKE-256") - { - return std::unique_ptr(new SHAKE_256(req.arg_as_integer(0, 256))); - } + if (req.algo_name() == "SHAKE-128") { + return std::unique_ptr(new SHAKE_128(req.arg_as_integer(0, 128))); + } + if (req.algo_name() == "SHAKE-256") { + return std::unique_ptr(new SHAKE_256(req.arg_as_integer(0, 256))); + } #endif #if defined(BOTAN_HAS_STREEBOG) - if(algo_spec == "Streebog-256") - { - return std::unique_ptr(new Streebog_256); - } - if(algo_spec == "Streebog-512") - { - return std::unique_ptr(new Streebog_512); - } + if (algo_spec == "Streebog-256") { + return std::unique_ptr(new Streebog_256); + } + if (algo_spec == "Streebog-512") { + return std::unique_ptr(new Streebog_512); + } #endif #if defined(BOTAN_HAS_SM3) - if(algo_spec == "SM3") - { - return std::unique_ptr(new SM3); - } + if (algo_spec == "SM3") { + return std::unique_ptr(new SM3); + } #endif #if defined(BOTAN_HAS_WHIRLPOOL) - if(req.algo_name() == "Whirlpool") - { - return std::unique_ptr(new Whirlpool); - } + if (req.algo_name() == "Whirlpool") { + return std::unique_ptr(new Whirlpool); + } #endif #if defined(BOTAN_HAS_PARALLEL_HASH) - if(req.algo_name() == "Parallel") - { - std::vector> hashes; + if (req.algo_name() == "Parallel") { + std::vector> hashes; - for(size_t i = 0; i != req.arg_count(); ++i) - { - auto h = HashFunction::create(req.arg(i)); - if(!h) - { - return nullptr; + for (size_t i = 0; i != req.arg_count(); ++i) { + auto h = HashFunction::create(req.arg(i)); + if (!h) { + return nullptr; } - hashes.push_back(std::move(h)); - } + hashes.push_back(std::move(h)); + } - return std::unique_ptr(new Parallel(hashes)); - } + return std::unique_ptr(new Parallel(hashes)); + } #endif #if defined(BOTAN_HAS_COMB4P) - if(req.algo_name() == "Comb4P" && req.arg_count() == 2) - { - std::unique_ptr h1(HashFunction::create(req.arg(0))); - std::unique_ptr h2(HashFunction::create(req.arg(1))); + if (req.algo_name() == "Comb4P" && req.arg_count() == 2) { + std::unique_ptr h1(HashFunction::create(req.arg(0))); + std::unique_ptr h2(HashFunction::create(req.arg(1))); - if(h1 && h2) - return std::unique_ptr(new Comb4P(h1.release(), h2.release())); - } + if (h1 && h2) return std::unique_ptr(new Comb4P(h1.release(), h2.release())); + } #endif - - return nullptr; - } - -//static -std::unique_ptr -HashFunction::create_or_throw(const std::string& algo, - const std::string& provider) - { - if(auto hash = HashFunction::create(algo, provider)) - { - return hash; - } - throw Lookup_Error("Hash", algo, provider); - } - -std::vector HashFunction::providers(const std::string& algo_spec) - { - return probe_providers_of(algo_spec, {"base", "openssl", "commoncrypto"}); - } - + return nullptr; } -/* -* Hash Function Identification -* (C) 1999-2008 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +// static +std::unique_ptr HashFunction::create_or_throw(const std::string& algo, + const std::string& provider) { + if (auto hash = HashFunction::create(algo, provider)) { + return hash; + } + throw Lookup_Error("Hash", algo, provider); +} +std::vector HashFunction::providers(const std::string& algo_spec) { + return probe_providers_of(algo_spec, {"base", "openssl", "commoncrypto"}); +} + +} // namespace Botan + +/* + * Hash Function Identification + * (C) 1999-2008 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { -const uint8_t MD5_PKCS_ID[] = { -0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, -0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; +const uint8_t MD5_PKCS_ID[] = {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; -const uint8_t RIPEMD_160_PKCS_ID[] = { -0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, -0x01, 0x05, 0x00, 0x04, 0x14 }; +const uint8_t RIPEMD_160_PKCS_ID[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, + 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14}; -const uint8_t SHA_160_PKCS_ID[] = { -0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, -0x1A, 0x05, 0x00, 0x04, 0x14 }; +const uint8_t SHA_160_PKCS_ID[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, + 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; -const uint8_t SHA_224_PKCS_ID[] = { -0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C }; +const uint8_t SHA_224_PKCS_ID[] = {0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C}; -const uint8_t SHA_256_PKCS_ID[] = { -0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; +const uint8_t SHA_256_PKCS_ID[] = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; -const uint8_t SHA_384_PKCS_ID[] = { -0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 }; +const uint8_t SHA_384_PKCS_ID[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; -const uint8_t SHA_512_PKCS_ID[] = { -0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 }; +const uint8_t SHA_512_PKCS_ID[] = {0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; -const uint8_t SHA_512_256_PKCS_ID[] = { -0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20 }; +const uint8_t SHA_512_256_PKCS_ID[] = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20}; -const uint8_t SHA3_224_PKCS_ID[] = { -0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, -0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1C }; +const uint8_t SHA3_224_PKCS_ID[] = {0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1C}; -const uint8_t SHA3_256_PKCS_ID[] = { -0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, -0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20 }; +const uint8_t SHA3_256_PKCS_ID[] = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20}; -const uint8_t SHA3_384_PKCS_ID[] = { -0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, -0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30 }; +const uint8_t SHA3_384_PKCS_ID[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30}; -const uint8_t SHA3_512_PKCS_ID[] = { -0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, -0x03, 0x04, 0x02, 0x0A, 0x05, 0x00, 0x04, 0x40 }; +const uint8_t SHA3_512_PKCS_ID[] = {0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x0A, 0x05, 0x00, 0x04, 0x40}; const uint8_t SM3_PKCS_ID[] = { -0x30, 0x30, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, -0x55, 0x01, 0x83, 0x11, 0x05, 0x00, 0x04, 0x20, + 0x30, 0x30, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x81, 0x1C, + 0xCF, 0x55, 0x01, 0x83, 0x11, 0x05, 0x00, 0x04, 0x20, }; -const uint8_t TIGER_PKCS_ID[] = { -0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, -0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, 0x00, 0x04, 0x18 }; +const uint8_t TIGER_PKCS_ID[] = {0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, + 0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, 0x00, 0x04, 0x18}; +} // namespace + +/* + * HashID as specified by PKCS + */ +std::vector pkcs_hash_id(const std::string& name) { + // Special case for SSL/TLS RSA signatures + if (name == "Parallel(MD5,SHA-160)") return std::vector(); + + // If you add a value to this function, also update test_hash_id.cpp + + if (name == "MD5") return std::vector(MD5_PKCS_ID, MD5_PKCS_ID + sizeof(MD5_PKCS_ID)); + + if (name == "RIPEMD-160") + return std::vector(RIPEMD_160_PKCS_ID, + RIPEMD_160_PKCS_ID + sizeof(RIPEMD_160_PKCS_ID)); + + if (name == "SHA-160" || name == "SHA-1" || name == "SHA1") + return std::vector(SHA_160_PKCS_ID, SHA_160_PKCS_ID + sizeof(SHA_160_PKCS_ID)); + + if (name == "SHA-224") + return std::vector(SHA_224_PKCS_ID, SHA_224_PKCS_ID + sizeof(SHA_224_PKCS_ID)); + + if (name == "SHA-256") + return std::vector(SHA_256_PKCS_ID, SHA_256_PKCS_ID + sizeof(SHA_256_PKCS_ID)); + + if (name == "SHA-384") + return std::vector(SHA_384_PKCS_ID, SHA_384_PKCS_ID + sizeof(SHA_384_PKCS_ID)); + + if (name == "SHA-512") + return std::vector(SHA_512_PKCS_ID, SHA_512_PKCS_ID + sizeof(SHA_512_PKCS_ID)); + + if (name == "SHA-512-256") + return std::vector(SHA_512_256_PKCS_ID, + SHA_512_256_PKCS_ID + sizeof(SHA_512_256_PKCS_ID)); + + if (name == "SHA-3(224)") + return std::vector(SHA3_224_PKCS_ID, SHA3_224_PKCS_ID + sizeof(SHA3_224_PKCS_ID)); + + if (name == "SHA-3(256)") + return std::vector(SHA3_256_PKCS_ID, SHA3_256_PKCS_ID + sizeof(SHA3_256_PKCS_ID)); + + if (name == "SHA-3(384)") + return std::vector(SHA3_384_PKCS_ID, SHA3_384_PKCS_ID + sizeof(SHA3_384_PKCS_ID)); + + if (name == "SHA-3(512)") + return std::vector(SHA3_512_PKCS_ID, SHA3_512_PKCS_ID + sizeof(SHA3_512_PKCS_ID)); + + if (name == "SM3") return std::vector(SM3_PKCS_ID, SM3_PKCS_ID + sizeof(SM3_PKCS_ID)); + + if (name == "Tiger(24,3)") + return std::vector(TIGER_PKCS_ID, TIGER_PKCS_ID + sizeof(TIGER_PKCS_ID)); + + throw Invalid_Argument("No PKCS #1 identifier for " + name); } /* -* HashID as specified by PKCS -*/ -std::vector pkcs_hash_id(const std::string& name) - { - // Special case for SSL/TLS RSA signatures - if(name == "Parallel(MD5,SHA-160)") - return std::vector(); + * HashID as specified by IEEE 1363/X9.31 + */ +uint8_t ieee1363_hash_id(const std::string& name) { + if (name == "SHA-160" || name == "SHA-1" || name == "SHA1") return 0x33; - // If you add a value to this function, also update test_hash_id.cpp + if (name == "SHA-224") return 0x38; + if (name == "SHA-256") return 0x34; + if (name == "SHA-384") return 0x36; + if (name == "SHA-512") return 0x35; - if(name == "MD5") - return std::vector(MD5_PKCS_ID, - MD5_PKCS_ID + sizeof(MD5_PKCS_ID)); + if (name == "RIPEMD-160") return 0x31; - if(name == "RIPEMD-160") - return std::vector(RIPEMD_160_PKCS_ID, - RIPEMD_160_PKCS_ID + sizeof(RIPEMD_160_PKCS_ID)); - - if(name == "SHA-160" || name == "SHA-1" || name == "SHA1") - return std::vector(SHA_160_PKCS_ID, - SHA_160_PKCS_ID + sizeof(SHA_160_PKCS_ID)); - - if(name == "SHA-224") - return std::vector(SHA_224_PKCS_ID, - SHA_224_PKCS_ID + sizeof(SHA_224_PKCS_ID)); - - if(name == "SHA-256") - return std::vector(SHA_256_PKCS_ID, - SHA_256_PKCS_ID + sizeof(SHA_256_PKCS_ID)); - - if(name == "SHA-384") - return std::vector(SHA_384_PKCS_ID, - SHA_384_PKCS_ID + sizeof(SHA_384_PKCS_ID)); - - if(name == "SHA-512") - return std::vector(SHA_512_PKCS_ID, - SHA_512_PKCS_ID + sizeof(SHA_512_PKCS_ID)); - - if(name == "SHA-512-256") - return std::vector(SHA_512_256_PKCS_ID, - SHA_512_256_PKCS_ID + sizeof(SHA_512_256_PKCS_ID)); - - if(name == "SHA-3(224)") - return std::vector(SHA3_224_PKCS_ID, - SHA3_224_PKCS_ID + sizeof(SHA3_224_PKCS_ID)); - - if(name == "SHA-3(256)") - return std::vector(SHA3_256_PKCS_ID, - SHA3_256_PKCS_ID + sizeof(SHA3_256_PKCS_ID)); - - if(name == "SHA-3(384)") - return std::vector(SHA3_384_PKCS_ID, - SHA3_384_PKCS_ID + sizeof(SHA3_384_PKCS_ID)); - - if(name == "SHA-3(512)") - return std::vector(SHA3_512_PKCS_ID, - SHA3_512_PKCS_ID + sizeof(SHA3_512_PKCS_ID)); - - if(name == "SM3") - return std::vector(SM3_PKCS_ID, SM3_PKCS_ID + sizeof(SM3_PKCS_ID)); - - if(name == "Tiger(24,3)") - return std::vector(TIGER_PKCS_ID, - TIGER_PKCS_ID + sizeof(TIGER_PKCS_ID)); - - throw Invalid_Argument("No PKCS #1 identifier for " + name); - } - -/* -* HashID as specified by IEEE 1363/X9.31 -*/ -uint8_t ieee1363_hash_id(const std::string& name) - { - if(name == "SHA-160" || name == "SHA-1" || name == "SHA1") - return 0x33; - - if(name == "SHA-224") return 0x38; - if(name == "SHA-256") return 0x34; - if(name == "SHA-384") return 0x36; - if(name == "SHA-512") return 0x35; - - if(name == "RIPEMD-160") return 0x31; - - if(name == "Whirlpool") return 0x37; - - return 0; - } + if (name == "Whirlpool") return 0x37; + return 0; } -/* -* Hex Encoding and Decoding -* (C) 2010 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * Hex Encoding and Decoding + * (C) 2010 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -void hex_encode(char output[], - const uint8_t input[], - size_t input_length, - bool uppercase) - { - static const uint8_t BIN_TO_HEX_UPPER[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F' }; +void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase) { + static const uint8_t BIN_TO_HEX_UPPER[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - static const uint8_t BIN_TO_HEX_LOWER[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f' }; + static const uint8_t BIN_TO_HEX_LOWER[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - const uint8_t* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER; - - for(size_t i = 0; i != input_length; ++i) - { - uint8_t x = input[i]; - output[2*i ] = tbl[(x >> 4) & 0x0F]; - output[2*i+1] = tbl[(x ) & 0x0F]; - } - } - -std::string hex_encode(const uint8_t input[], - size_t input_length, - bool uppercase) - { - std::string output(2 * input_length, 0); - - if(input_length) - hex_encode(&output.front(), input, input_length, uppercase); - - return output; - } - -size_t hex_decode(uint8_t output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool ignore_ws) - { - /* - * Mapping of hex characters to either their binary equivalent - * or to an error code. - * If valid hex (0-9 A-F a-f), the value. - * If whitespace, then 0x80 - * Otherwise 0xFF - * Warning: this table assumes ASCII character encodings - */ - - static const uint8_t HEX_TO_BIN[256] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, - 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - - uint8_t* out_ptr = output; - bool top_nibble = true; - - clear_mem(output, input_length / 2); - - for(size_t i = 0; i != input_length; ++i) - { - const uint8_t bin = HEX_TO_BIN[static_cast(input[i])]; - - if(bin >= 0x10) - { - if(bin == 0x80 && ignore_ws) - continue; - - std::string bad_char(1, input[i]); - if(bad_char == "\t") - bad_char = "\\t"; - else if(bad_char == "\n") - bad_char = "\\n"; - - throw Invalid_Argument( - std::string("hex_decode: invalid hex character '") + - bad_char + "'"); - } - - if(top_nibble) - *out_ptr |= bin << 4; - else - *out_ptr |= bin; - - top_nibble = !top_nibble; - if(top_nibble) - ++out_ptr; - } - - input_consumed = input_length; - size_t written = (out_ptr - output); - - /* - * We only got half of a uint8_t at the end; zap the half-written - * output and mark it as unread - */ - if(!top_nibble) - { - *out_ptr = 0; - input_consumed -= 1; - } - - return written; - } - -size_t hex_decode(uint8_t output[], - const char input[], - size_t input_length, - bool ignore_ws) - { - size_t consumed = 0; - size_t written = hex_decode(output, input, input_length, - consumed, ignore_ws); - - if(consumed != input_length) - throw Invalid_Argument("hex_decode: input did not have full bytes"); - - return written; - } - -size_t hex_decode(uint8_t output[], - const std::string& input, - bool ignore_ws) - { - return hex_decode(output, input.data(), input.length(), ignore_ws); - } - -secure_vector hex_decode_locked(const char input[], - size_t input_length, - bool ignore_ws) - { - secure_vector bin(1 + input_length / 2); - - size_t written = hex_decode(bin.data(), - input, - input_length, - ignore_ws); - - bin.resize(written); - return bin; - } - -secure_vector hex_decode_locked(const std::string& input, - bool ignore_ws) - { - return hex_decode_locked(input.data(), input.size(), ignore_ws); - } - -std::vector hex_decode(const char input[], - size_t input_length, - bool ignore_ws) - { - std::vector bin(1 + input_length / 2); - - size_t written = hex_decode(bin.data(), - input, - input_length, - ignore_ws); - - bin.resize(written); - return bin; - } - -std::vector hex_decode(const std::string& input, - bool ignore_ws) - { - return hex_decode(input.data(), input.size(), ignore_ws); - } + const uint8_t* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER; + for (size_t i = 0; i != input_length; ++i) { + uint8_t x = input[i]; + output[2 * i] = tbl[(x >> 4) & 0x0F]; + output[2 * i + 1] = tbl[(x) & 0x0F]; + } } -/* -* HMAC -* (C) 1999-2007,2014 Jack Lloyd -* 2007 Yves Jerschow -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +std::string hex_encode(const uint8_t input[], size_t input_length, bool uppercase) { + std::string output(2 * input_length, 0); + + if (input_length) hex_encode(&output.front(), input, input_length, uppercase); + + return output; +} + +size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t& input_consumed, + bool ignore_ws) { + /* + * Mapping of hex characters to either their binary equivalent + * or to an error code. + * If valid hex (0-9 A-F a-f), the value. + * If whitespace, then 0x80 + * Otherwise 0xFF + * Warning: this table assumes ASCII character encodings + */ + + static const uint8_t HEX_TO_BIN[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF}; + + uint8_t* out_ptr = output; + bool top_nibble = true; + + clear_mem(output, input_length / 2); + + for (size_t i = 0; i != input_length; ++i) { + const uint8_t bin = HEX_TO_BIN[static_cast(input[i])]; + + if (bin >= 0x10) { + if (bin == 0x80 && ignore_ws) continue; + + std::string bad_char(1, input[i]); + if (bad_char == "\t") + bad_char = "\\t"; + else if (bad_char == "\n") + bad_char = "\\n"; + + throw Invalid_Argument(std::string("hex_decode: invalid hex character '") + bad_char + + "'"); + } + + if (top_nibble) + *out_ptr |= bin << 4; + else + *out_ptr |= bin; + + top_nibble = !top_nibble; + if (top_nibble) ++out_ptr; + } + + input_consumed = input_length; + size_t written = (out_ptr - output); + + /* + * We only got half of a uint8_t at the end; zap the half-written + * output and mark it as unread + */ + if (!top_nibble) { + *out_ptr = 0; + input_consumed -= 1; + } + + return written; +} + +size_t hex_decode(uint8_t output[], const char input[], size_t input_length, bool ignore_ws) { + size_t consumed = 0; + size_t written = hex_decode(output, input, input_length, consumed, ignore_ws); + + if (consumed != input_length) + throw Invalid_Argument("hex_decode: input did not have full bytes"); + + return written; +} + +size_t hex_decode(uint8_t output[], const std::string& input, bool ignore_ws) { + return hex_decode(output, input.data(), input.length(), ignore_ws); +} + +secure_vector hex_decode_locked(const char input[], size_t input_length, bool ignore_ws) { + secure_vector bin(1 + input_length / 2); + + size_t written = hex_decode(bin.data(), input, input_length, ignore_ws); + + bin.resize(written); + return bin; +} + +secure_vector hex_decode_locked(const std::string& input, bool ignore_ws) { + return hex_decode_locked(input.data(), input.size(), ignore_ws); +} + +std::vector hex_decode(const char input[], size_t input_length, bool ignore_ws) { + std::vector bin(1 + input_length / 2); + + size_t written = hex_decode(bin.data(), input, input_length, ignore_ws); + + bin.resize(written); + return bin; +} + +std::vector hex_decode(const std::string& input, bool ignore_ws) { + return hex_decode(input.data(), input.size(), ignore_ws); +} + +} // namespace Botan +/* + * HMAC + * (C) 1999-2007,2014 Jack Lloyd + * 2007 Yves Jerschow + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Update a HMAC Calculation -*/ -void HMAC::add_data(const uint8_t input[], size_t length) - { - verify_key_set(m_ikey.empty() == false); - m_hash->update(input, length); - } - -/* -* Finalize a HMAC Calculation -*/ -void HMAC::final_result(uint8_t mac[]) - { - verify_key_set(m_okey.empty() == false); - m_hash->final(mac); - m_hash->update(m_okey); - m_hash->update(mac, m_hash_output_length); - m_hash->final(mac); - m_hash->update(m_ikey); - } - -Key_Length_Specification HMAC::key_spec() const - { - // Support very long lengths for things like PBKDF2 and the TLS PRF - return Key_Length_Specification(0, 4096); - } - -size_t HMAC::output_length() const - { - return m_hash_output_length; - } - -/* -* HMAC Key Schedule -*/ -void HMAC::key_schedule(const uint8_t key[], size_t length) - { - const uint8_t ipad = 0x36; - const uint8_t opad = 0x5C; - - m_hash->clear(); - - m_ikey.resize(m_hash_block_size); - set_mem(m_ikey.data(), m_hash_block_size, ipad); - - m_okey.resize(m_hash_block_size); - set_mem(m_okey.data(), m_hash_block_size, opad); - - if(length > m_hash_block_size) - { - m_hash->update(key, length); - m_hash->final(m_ikey.data()); - - xor_buf(m_okey.data(), m_ikey.data(), m_hash_output_length); - - for(size_t i = 0; i != m_hash_output_length; ++i) - { - m_ikey[i] ^= ipad; - } - } - else - { - xor_buf(m_ikey, key, length); - xor_buf(m_okey, key, length); - } - - m_hash->update(m_ikey); - } - -/* -* Clear memory of sensitive data -*/ -void HMAC::clear() - { - m_hash->clear(); - zap(m_ikey); - zap(m_okey); - } - -/* -* Return the name of this type -*/ -std::string HMAC::name() const - { - return "HMAC(" + m_hash->name() + ")"; - } - -/* -* Return a clone of this object -*/ -MessageAuthenticationCode* HMAC::clone() const - { - return new HMAC(m_hash->clone()); - } - -/* -* HMAC Constructor -*/ -HMAC::HMAC(HashFunction* hash) : - m_hash(hash), - m_hash_output_length(m_hash->output_length()), - m_hash_block_size(m_hash->hash_block_size()) - { - BOTAN_ARG_CHECK(m_hash_block_size >= m_hash_output_length, - "HMAC is not compatible with this hash function"); - } - + * Update a HMAC Calculation + */ +void HMAC::add_data(const uint8_t input[], size_t length) { + verify_key_set(m_ikey.empty() == false); + m_hash->update(input, length); } -/* -* HMAC_DRBG -* (C) 2014,2015,2016 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Finalize a HMAC Calculation + */ +void HMAC::final_result(uint8_t mac[]) { + verify_key_set(m_okey.empty() == false); + m_hash->final(mac); + m_hash->update(m_okey); + m_hash->update(mac, m_hash_output_length); + m_hash->final(mac); + m_hash->update(m_ikey); +} + +Key_Length_Specification HMAC::key_spec() const { + // Support very long lengths for things like PBKDF2 and the TLS PRF + return Key_Length_Specification(0, 4096); +} + +size_t HMAC::output_length() const { return m_hash_output_length; } + +/* + * HMAC Key Schedule + */ +void HMAC::key_schedule(const uint8_t key[], size_t length) { + const uint8_t ipad = 0x36; + const uint8_t opad = 0x5C; + + m_hash->clear(); + + m_ikey.resize(m_hash_block_size); + set_mem(m_ikey.data(), m_hash_block_size, ipad); + + m_okey.resize(m_hash_block_size); + set_mem(m_okey.data(), m_hash_block_size, opad); + + if (length > m_hash_block_size) { + m_hash->update(key, length); + m_hash->final(m_ikey.data()); + + xor_buf(m_okey.data(), m_ikey.data(), m_hash_output_length); + + for (size_t i = 0; i != m_hash_output_length; ++i) { + m_ikey[i] ^= ipad; + } + } else { + xor_buf(m_ikey, key, length); + xor_buf(m_okey, key, length); + } + + m_hash->update(m_ikey); +} + +/* + * Clear memory of sensitive data + */ +void HMAC::clear() { + m_hash->clear(); + zap(m_ikey); + zap(m_okey); +} + +/* + * Return the name of this type + */ +std::string HMAC::name() const { return "HMAC(" + m_hash->name() + ")"; } + +/* + * Return a clone of this object + */ +MessageAuthenticationCode* HMAC::clone() const { return new HMAC(m_hash->clone()); } + +/* + * HMAC Constructor + */ +HMAC::HMAC(HashFunction* hash) + : m_hash(hash), + m_hash_output_length(m_hash->output_length()), + m_hash_block_size(m_hash->hash_block_size()) { + BOTAN_ARG_CHECK(m_hash_block_size >= m_hash_output_length, + "HMAC is not compatible with this hash function"); +} + +} // namespace Botan +/* + * HMAC_DRBG + * (C) 2014,2015,2016 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf, - RandomNumberGenerator& underlying_rng, - size_t reseed_interval, - size_t max_number_of_bytes_per_request) : - Stateful_RNG(underlying_rng, reseed_interval), - m_mac(std::move(prf)), - m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) - { - BOTAN_ASSERT_NONNULL(m_mac); + RandomNumberGenerator& underlying_rng, size_t reseed_interval, + size_t max_number_of_bytes_per_request) + : Stateful_RNG(underlying_rng, reseed_interval), + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) { + BOTAN_ASSERT_NONNULL(m_mac); - if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) - { - throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); - } + if (m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } - clear(); - } - -HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf, - RandomNumberGenerator& underlying_rng, - Entropy_Sources& entropy_sources, - size_t reseed_interval, - size_t max_number_of_bytes_per_request ) : - Stateful_RNG(underlying_rng, entropy_sources, reseed_interval), - m_mac(std::move(prf)), - m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) - { - BOTAN_ASSERT_NONNULL(m_mac); - - if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) - { - throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); - } - - clear(); - } - -HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf, - Entropy_Sources& entropy_sources, - size_t reseed_interval, - size_t max_number_of_bytes_per_request) : - Stateful_RNG(entropy_sources, reseed_interval), - m_mac(std::move(prf)), - m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) - { - BOTAN_ASSERT_NONNULL(m_mac); - - if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) - { - throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); - } - - clear(); - } - -HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf) : - Stateful_RNG(), - m_mac(std::move(prf)), - m_max_number_of_bytes_per_request(64*1024) - { - BOTAN_ASSERT_NONNULL(m_mac); - clear(); - } - -void HMAC_DRBG::clear() - { - Stateful_RNG::clear(); - - m_V.resize(m_mac->output_length()); - for(size_t i = 0; i != m_V.size(); ++i) - m_V[i] = 0x01; - m_mac->set_key(std::vector(m_mac->output_length(), 0x00)); - } - -std::string HMAC_DRBG::name() const - { - return "HMAC_DRBG(" + m_mac->name() + ")"; - } - -void HMAC_DRBG::randomize(uint8_t output[], size_t output_len) - { - randomize_with_input(output, output_len, nullptr, 0); - } - -/* -* HMAC_DRBG generation -* See NIST SP800-90A section 10.1.2.5 -*/ -void HMAC_DRBG::randomize_with_input(uint8_t output[], size_t output_len, - const uint8_t input[], size_t input_len) - { - while(output_len > 0) - { - size_t this_req = std::min(m_max_number_of_bytes_per_request, output_len); - output_len -= this_req; - - reseed_check(); - - if(input_len > 0) - { - update(input, input_len); - } - - while(this_req) - { - const size_t to_copy = std::min(this_req, m_V.size()); - m_mac->update(m_V.data(), m_V.size()); - m_mac->final(m_V.data()); - copy_mem(output, m_V.data(), to_copy); - - output += to_copy; - this_req -= to_copy; - } - - update(input, input_len); - } - - } - -/* -* Reset V and the mac key with new values -* See NIST SP800-90A section 10.1.2.2 -*/ -void HMAC_DRBG::update(const uint8_t input[], size_t input_len) - { - m_mac->update(m_V); - m_mac->update(0x00); - m_mac->update(input, input_len); - m_mac->set_key(m_mac->final()); - - m_mac->update(m_V.data(), m_V.size()); - m_mac->final(m_V.data()); - - if(input_len > 0) - { - m_mac->update(m_V); - m_mac->update(0x01); - m_mac->update(input, input_len); - m_mac->set_key(m_mac->final()); - - m_mac->update(m_V.data(), m_V.size()); - m_mac->final(m_V.data()); - } - } - -void HMAC_DRBG::add_entropy(const uint8_t input[], size_t input_len) - { - update(input, input_len); - - if(8*input_len >= security_level()) - { - reset_reseed_counter(); - } - } - -size_t HMAC_DRBG::security_level() const - { - // security strength of the hash function - // for pre-image resistance (see NIST SP 800-57) - // SHA-160: 128 bits, SHA-224, SHA-512/224: 192 bits, - // SHA-256, SHA-512/256, SHA-384, SHA-512: >= 256 bits - // NIST SP 800-90A only supports up to 256 bits though - if(m_mac->output_length() < 32) - { - return (m_mac->output_length() - 4) * 8; - } - else - { - return 32 * 8; - } - } + clear(); } -/* -* KDF Retrieval -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf, + RandomNumberGenerator& underlying_rng, Entropy_Sources& entropy_sources, + size_t reseed_interval, size_t max_number_of_bytes_per_request) + : Stateful_RNG(underlying_rng, entropy_sources, reseed_interval), + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) { + BOTAN_ASSERT_NONNULL(m_mac); + + if (m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } + + clear(); +} + +HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf, + Entropy_Sources& entropy_sources, size_t reseed_interval, + size_t max_number_of_bytes_per_request) + : Stateful_RNG(entropy_sources, reseed_interval), + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) { + BOTAN_ASSERT_NONNULL(m_mac); + + if (m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } + + clear(); +} + +HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf) + : Stateful_RNG(), m_mac(std::move(prf)), m_max_number_of_bytes_per_request(64 * 1024) { + BOTAN_ASSERT_NONNULL(m_mac); + clear(); +} + +void HMAC_DRBG::clear() { + Stateful_RNG::clear(); + + m_V.resize(m_mac->output_length()); + for (size_t i = 0; i != m_V.size(); ++i) m_V[i] = 0x01; + m_mac->set_key(std::vector(m_mac->output_length(), 0x00)); +} + +std::string HMAC_DRBG::name() const { return "HMAC_DRBG(" + m_mac->name() + ")"; } + +void HMAC_DRBG::randomize(uint8_t output[], size_t output_len) { + randomize_with_input(output, output_len, nullptr, 0); +} + +/* + * HMAC_DRBG generation + * See NIST SP800-90A section 10.1.2.5 + */ +void HMAC_DRBG::randomize_with_input(uint8_t output[], size_t output_len, const uint8_t input[], + size_t input_len) { + while (output_len > 0) { + size_t this_req = std::min(m_max_number_of_bytes_per_request, output_len); + output_len -= this_req; + + reseed_check(); + + if (input_len > 0) { + update(input, input_len); + } + + while (this_req) { + const size_t to_copy = std::min(this_req, m_V.size()); + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); + copy_mem(output, m_V.data(), to_copy); + + output += to_copy; + this_req -= to_copy; + } + + update(input, input_len); + } +} + +/* + * Reset V and the mac key with new values + * See NIST SP800-90A section 10.1.2.2 + */ +void HMAC_DRBG::update(const uint8_t input[], size_t input_len) { + m_mac->update(m_V); + m_mac->update(0x00); + m_mac->update(input, input_len); + m_mac->set_key(m_mac->final()); + + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); + + if (input_len > 0) { + m_mac->update(m_V); + m_mac->update(0x01); + m_mac->update(input, input_len); + m_mac->set_key(m_mac->final()); + + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); + } +} + +void HMAC_DRBG::add_entropy(const uint8_t input[], size_t input_len) { + update(input, input_len); + + if (8 * input_len >= security_level()) { + reset_reseed_counter(); + } +} + +size_t HMAC_DRBG::security_level() const { + // security strength of the hash function + // for pre-image resistance (see NIST SP 800-57) + // SHA-160: 128 bits, SHA-224, SHA-512/224: 192 bits, + // SHA-256, SHA-512/256, SHA-384, SHA-512: >= 256 bits + // NIST SP 800-90A only supports up to 256 bits though + if (m_mac->output_length() < 32) { + return (m_mac->output_length() - 4) * 8; + } else { + return 32 * 8; + } +} +} // namespace Botan +/* + * KDF Retrieval + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_HKDF) #endif @@ -10837,247 +9083,203 @@ namespace Botan { namespace { -template -std::unique_ptr -kdf_create_mac_or_hash(const std::string& nm) - { - if(auto mac = MessageAuthenticationCode::create(nm)) - return std::unique_ptr(new KDF_Type(mac.release())); +template +std::unique_ptr kdf_create_mac_or_hash(const std::string& nm) { + if (auto mac = MessageAuthenticationCode::create(nm)) + return std::unique_ptr(new KDF_Type(mac.release())); - if(auto mac = MessageAuthenticationCode::create("HMAC(" + nm + ")")) - return std::unique_ptr(new KDF_Type(mac.release())); - - return nullptr; - } + if (auto mac = MessageAuthenticationCode::create("HMAC(" + nm + ")")) + return std::unique_ptr(new KDF_Type(mac.release())); + return nullptr; } -std::unique_ptr KDF::create(const std::string& algo_spec, - const std::string& provider) - { - const SCAN_Name req(algo_spec); +} // namespace + +std::unique_ptr KDF::create(const std::string& algo_spec, const std::string& provider) { + const SCAN_Name req(algo_spec); #if defined(BOTAN_HAS_HKDF) - if(req.algo_name() == "HKDF" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - return kdf_create_mac_or_hash(req.arg(0)); - } - } + if (req.algo_name() == "HKDF" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + return kdf_create_mac_or_hash(req.arg(0)); + } + } - if(req.algo_name() == "HKDF-Extract" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - return kdf_create_mac_or_hash(req.arg(0)); - } - } + if (req.algo_name() == "HKDF-Extract" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + return kdf_create_mac_or_hash(req.arg(0)); + } + } - if(req.algo_name() == "HKDF-Expand" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - return kdf_create_mac_or_hash(req.arg(0)); - } - } + if (req.algo_name() == "HKDF-Expand" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + return kdf_create_mac_or_hash(req.arg(0)); + } + } #endif #if defined(BOTAN_HAS_KDF2) - if(req.algo_name() == "KDF2" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - if(auto hash = HashFunction::create(req.arg(0))) - return std::unique_ptr(new KDF2(hash.release())); - } - } + if (req.algo_name() == "KDF2" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + if (auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new KDF2(hash.release())); + } + } #endif #if defined(BOTAN_HAS_KDF1_18033) - if(req.algo_name() == "KDF1-18033" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - if(auto hash = HashFunction::create(req.arg(0))) - return std::unique_ptr(new KDF1_18033(hash.release())); - } - } + if (req.algo_name() == "KDF1-18033" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + if (auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new KDF1_18033(hash.release())); + } + } #endif #if defined(BOTAN_HAS_KDF1) - if(req.algo_name() == "KDF1" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - if(auto hash = HashFunction::create(req.arg(0))) - return std::unique_ptr(new KDF1(hash.release())); - } - } + if (req.algo_name() == "KDF1" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + if (auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new KDF1(hash.release())); + } + } #endif #if defined(BOTAN_HAS_TLS_V10_PRF) - if(req.algo_name() == "TLS-PRF" && req.arg_count() == 0) - { - if(provider.empty() || provider == "base") - { - return std::unique_ptr(new TLS_PRF); - } - } + if (req.algo_name() == "TLS-PRF" && req.arg_count() == 0) { + if (provider.empty() || provider == "base") { + return std::unique_ptr(new TLS_PRF); + } + } #endif #if defined(BOTAN_HAS_TLS_V12_PRF) - if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - return kdf_create_mac_or_hash(req.arg(0)); - } - } + if (req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + return kdf_create_mac_or_hash(req.arg(0)); + } + } #endif #if defined(BOTAN_HAS_X942_PRF) - if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - return std::unique_ptr(new X942_PRF(req.arg(0))); - } - } + if (req.algo_name() == "X9.42-PRF" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + return std::unique_ptr(new X942_PRF(req.arg(0))); + } + } #endif #if defined(BOTAN_HAS_SP800_108) - if(req.algo_name() == "SP800-108-Counter" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - return kdf_create_mac_or_hash(req.arg(0)); - } - } + if (req.algo_name() == "SP800-108-Counter" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + return kdf_create_mac_or_hash(req.arg(0)); + } + } - if(req.algo_name() == "SP800-108-Feedback" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - return kdf_create_mac_or_hash(req.arg(0)); - } - } + if (req.algo_name() == "SP800-108-Feedback" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + return kdf_create_mac_or_hash(req.arg(0)); + } + } - if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - return kdf_create_mac_or_hash(req.arg(0)); - } - } + if (req.algo_name() == "SP800-108-Pipeline" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + return kdf_create_mac_or_hash(req.arg(0)); + } + } #endif #if defined(BOTAN_HAS_SP800_56A) - if(req.algo_name() == "SP800-56A" && req.arg_count() == 1) - { - if(auto hash = HashFunction::create(req.arg(0))) - return std::unique_ptr(new SP800_56A_Hash(hash.release())); - if(auto mac = MessageAuthenticationCode::create(req.arg(0))) - return std::unique_ptr(new SP800_56A_HMAC(mac.release())); - } + if (req.algo_name() == "SP800-56A" && req.arg_count() == 1) { + if (auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new SP800_56A_Hash(hash.release())); + if (auto mac = MessageAuthenticationCode::create(req.arg(0))) + return std::unique_ptr(new SP800_56A_HMAC(mac.release())); + } #endif #if defined(BOTAN_HAS_SP800_56C) - if(req.algo_name() == "SP800-56C" && req.arg_count() == 1) - { - std::unique_ptr exp(kdf_create_mac_or_hash(req.arg(0))); - if(exp) - { - if(auto mac = MessageAuthenticationCode::create(req.arg(0))) - return std::unique_ptr(new SP800_56C(mac.release(), exp.release())); + if (req.algo_name() == "SP800-56C" && req.arg_count() == 1) { + std::unique_ptr exp(kdf_create_mac_or_hash(req.arg(0))); + if (exp) { + if (auto mac = MessageAuthenticationCode::create(req.arg(0))) + return std::unique_ptr(new SP800_56C(mac.release(), exp.release())); - if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) - return std::unique_ptr(new SP800_56C(mac.release(), exp.release())); - } - } + if (auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) + return std::unique_ptr(new SP800_56C(mac.release(), exp.release())); + } + } #endif - BOTAN_UNUSED(req); - BOTAN_UNUSED(provider); - - return nullptr; - } - -//static -std::unique_ptr -KDF::create_or_throw(const std::string& algo, - const std::string& provider) - { - if(auto kdf = KDF::create(algo, provider)) - { - return kdf; - } - throw Lookup_Error("KDF", algo, provider); - } - -std::vector KDF::providers(const std::string& algo_spec) - { - return probe_providers_of(algo_spec, { "base" }); - } - -KDF* get_kdf(const std::string& algo_spec) - { - SCAN_Name request(algo_spec); - - if(request.algo_name() == "Raw") - return nullptr; // No KDF - - //return KDF::create_or_throw(algo_spec).release(); - auto kdf = KDF::create(algo_spec); - if(!kdf) - throw Algorithm_Not_Found(algo_spec); - return kdf.release(); - } + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + return nullptr; } -/* -* KDF2 -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +// static +std::unique_ptr KDF::create_or_throw(const std::string& algo, const std::string& provider) { + if (auto kdf = KDF::create(algo, provider)) { + return kdf; + } + throw Lookup_Error("KDF", algo, provider); +} + +std::vector KDF::providers(const std::string& algo_spec) { + return probe_providers_of(algo_spec, {"base"}); +} + +KDF* get_kdf(const std::string& algo_spec) { + SCAN_Name request(algo_spec); + + if (request.algo_name() == "Raw") return nullptr; // No KDF + + // return KDF::create_or_throw(algo_spec).release(); + auto kdf = KDF::create(algo_spec); + if (!kdf) throw Algorithm_Not_Found(algo_spec); + return kdf.release(); +} + +} // namespace Botan +/* + * KDF2 + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -size_t KDF2::kdf(uint8_t key[], size_t key_len, - const uint8_t secret[], size_t secret_len, - const uint8_t salt[], size_t salt_len, - const uint8_t label[], size_t label_len) const - { - uint32_t counter = 1; - secure_vector h; +size_t KDF2::kdf(uint8_t key[], size_t key_len, const uint8_t secret[], size_t secret_len, + const uint8_t salt[], size_t salt_len, const uint8_t label[], + size_t label_len) const { + uint32_t counter = 1; + secure_vector h; - size_t offset = 0; - while(offset != key_len && counter != 0) - { - m_hash->update(secret, secret_len); - m_hash->update_be(counter++); - m_hash->update(label, label_len); - m_hash->update(salt, salt_len); - m_hash->final(h); + size_t offset = 0; + while (offset != key_len && counter != 0) { + m_hash->update(secret, secret_len); + m_hash->update_be(counter++); + m_hash->update(label, label_len); + m_hash->update(salt, salt_len); + m_hash->final(h); - const size_t added = std::min(h.size(), key_len - offset); - copy_mem(&key[offset], h.data(), added); - offset += added; - } - - return offset; - } + const size_t added = std::min(h.size(), key_len - offset); + copy_mem(&key[offset], h.data(), added); + offset += added; + } + return offset; } -/* -* Message Authentication Code base class -* (C) 1999-2008 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * Message Authentication Code base class + * (C) 1999-2008 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_CBC_MAC) #endif @@ -11102,478 +9304,408 @@ size_t KDF2::kdf(uint8_t key[], size_t key_len, namespace Botan { -std::unique_ptr -MessageAuthenticationCode::create(const std::string& algo_spec, - const std::string& provider) - { - const SCAN_Name req(algo_spec); +std::unique_ptr MessageAuthenticationCode::create( + const std::string& algo_spec, const std::string& provider) { + const SCAN_Name req(algo_spec); #if defined(BOTAN_HAS_GMAC) - if(req.algo_name() == "GMAC" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - if(auto bc = BlockCipher::create(req.arg(0))) - return std::unique_ptr(new GMAC(bc.release())); - } - } + if (req.algo_name() == "GMAC" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + if (auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new GMAC(bc.release())); + } + } #endif #if defined(BOTAN_HAS_HMAC) - if(req.algo_name() == "HMAC" && req.arg_count() == 1) - { - // TODO OpenSSL - if(provider.empty() || provider == "base") - { - if(auto h = HashFunction::create(req.arg(0))) - return std::unique_ptr(new HMAC(h.release())); - } - } + if (req.algo_name() == "HMAC" && req.arg_count() == 1) { + // TODO OpenSSL + if (provider.empty() || provider == "base") { + if (auto h = HashFunction::create(req.arg(0))) + return std::unique_ptr(new HMAC(h.release())); + } + } #endif #if defined(BOTAN_HAS_POLY1305) - if(req.algo_name() == "Poly1305" && req.arg_count() == 0) - { - if(provider.empty() || provider == "base") - return std::unique_ptr(new Poly1305); - } + if (req.algo_name() == "Poly1305" && req.arg_count() == 0) { + if (provider.empty() || provider == "base") + return std::unique_ptr(new Poly1305); + } #endif #if defined(BOTAN_HAS_SIPHASH) - if(req.algo_name() == "SipHash") - { - if(provider.empty() || provider == "base") - { - return std::unique_ptr( - new SipHash(req.arg_as_integer(0, 2), req.arg_as_integer(1, 4))); - } - } + if (req.algo_name() == "SipHash") { + if (provider.empty() || provider == "base") { + return std::unique_ptr( + new SipHash(req.arg_as_integer(0, 2), req.arg_as_integer(1, 4))); + } + } #endif #if defined(BOTAN_HAS_CMAC) - if((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1) - { - // TODO: OpenSSL CMAC - if(provider.empty() || provider == "base") - { - if(auto bc = BlockCipher::create(req.arg(0))) - return std::unique_ptr(new CMAC(bc.release())); - } - } + if ((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1) { + // TODO: OpenSSL CMAC + if (provider.empty() || provider == "base") { + if (auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new CMAC(bc.release())); + } + } #endif - #if defined(BOTAN_HAS_CBC_MAC) - if(req.algo_name() == "CBC-MAC" && req.arg_count() == 1) - { - if(provider.empty() || provider == "base") - { - if(auto bc = BlockCipher::create(req.arg(0))) - return std::unique_ptr(new CBC_MAC(bc.release())); - } - } + if (req.algo_name() == "CBC-MAC" && req.arg_count() == 1) { + if (provider.empty() || provider == "base") { + if (auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new CBC_MAC(bc.release())); + } + } #endif #if defined(BOTAN_HAS_ANSI_X919_MAC) - if(req.algo_name() == "X9.19-MAC") - { - if(provider.empty() || provider == "base") - { - return std::unique_ptr(new ANSI_X919_MAC); - } - } + if (req.algo_name() == "X9.19-MAC") { + if (provider.empty() || provider == "base") { + return std::unique_ptr(new ANSI_X919_MAC); + } + } #endif - BOTAN_UNUSED(req); - BOTAN_UNUSED(provider); - - return nullptr; - } - -std::vector -MessageAuthenticationCode::providers(const std::string& algo_spec) - { - return probe_providers_of(algo_spec, {"base", "openssl"}); - } - -//static -std::unique_ptr -MessageAuthenticationCode::create_or_throw(const std::string& algo, - const std::string& provider) - { - if(auto mac = MessageAuthenticationCode::create(algo, provider)) - { - return mac; - } - throw Lookup_Error("MAC", algo, provider); - } - -void MessageAuthenticationCode::start_msg(const uint8_t nonce[], size_t nonce_len) - { - BOTAN_UNUSED(nonce); - if(nonce_len > 0) - throw Invalid_IV_Length(name(), nonce_len); - } - -/* -* Default (deterministic) MAC verification operation -*/ -bool MessageAuthenticationCode::verify_mac(const uint8_t mac[], size_t length) - { - secure_vector our_mac = final(); - - if(our_mac.size() != length) - return false; - - return constant_time_compare(our_mac.data(), mac, length); - } + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + return nullptr; } -/* -* Merkle-Damgard Hash Function -* (C) 1999-2008,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +std::vector MessageAuthenticationCode::providers(const std::string& algo_spec) { + return probe_providers_of(algo_spec, {"base", "openssl"}); +} + +// static +std::unique_ptr MessageAuthenticationCode::create_or_throw( + const std::string& algo, const std::string& provider) { + if (auto mac = MessageAuthenticationCode::create(algo, provider)) { + return mac; + } + throw Lookup_Error("MAC", algo, provider); +} + +void MessageAuthenticationCode::start_msg(const uint8_t nonce[], size_t nonce_len) { + BOTAN_UNUSED(nonce); + if (nonce_len > 0) throw Invalid_IV_Length(name(), nonce_len); +} + +/* + * Default (deterministic) MAC verification operation + */ +bool MessageAuthenticationCode::verify_mac(const uint8_t mac[], size_t length) { + secure_vector our_mac = final(); + + if (our_mac.size() != length) return false; + + return constant_time_compare(our_mac.data(), mac, length); +} + +} // namespace Botan +/* + * Merkle-Damgard Hash Function + * (C) 1999-2008,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* MDx_HashFunction Constructor -*/ -MDx_HashFunction::MDx_HashFunction(size_t block_len, - bool byte_big_endian, - bool bit_big_endian, - uint8_t cnt_size) : - m_pad_char(bit_big_endian == true ? 0x80 : 0x01), - m_counter_size(cnt_size), - m_block_bits(static_cast(ceil_log2(block_len))), - m_count_big_endian(byte_big_endian), - m_count(0), - m_buffer(block_len), - m_position(0) - { - if(!is_power_of_2(block_len)) - throw Invalid_Argument("MDx_HashFunction block length must be a power of 2"); - if(m_block_bits < 3 || m_block_bits > 16) - throw Invalid_Argument("MDx_HashFunction block size too large or too small"); - if(m_counter_size < 8 || m_counter_size > block_len) - throw Invalid_State("MDx_HashFunction invalid counter length"); - } - -/* -* Clear memory of sensitive data -*/ -void MDx_HashFunction::clear() - { - zeroise(m_buffer); - m_count = m_position = 0; - } - -/* -* Update the hash -*/ -void MDx_HashFunction::add_data(const uint8_t input[], size_t length) - { - const size_t block_len = static_cast(1) << m_block_bits; - - m_count += length; - - if(m_position) - { - buffer_insert(m_buffer, m_position, input, length); - - if(m_position + length >= block_len) - { - compress_n(m_buffer.data(), 1); - input += (block_len - m_position); - length -= (block_len - m_position); - m_position = 0; - } - } - - // Just in case the compiler can't figure out block_len is a power of 2 - const size_t full_blocks = length >> m_block_bits; - const size_t remaining = length & (block_len - 1); - - if(full_blocks > 0) - { - compress_n(input, full_blocks); - } - - buffer_insert(m_buffer, m_position, input + full_blocks * block_len, remaining); - m_position += remaining; - } - -/* -* Finalize a hash -*/ -void MDx_HashFunction::final_result(uint8_t output[]) - { - const size_t block_len = static_cast(1) << m_block_bits; - - clear_mem(&m_buffer[m_position], block_len - m_position); - m_buffer[m_position] = m_pad_char; - - if(m_position >= block_len - m_counter_size) - { - compress_n(m_buffer.data(), 1); - zeroise(m_buffer); - } - - write_count(&m_buffer[block_len - m_counter_size]); - - compress_n(m_buffer.data(), 1); - copy_out(output); - clear(); - } - -/* -* Write the count bits to the buffer -*/ -void MDx_HashFunction::write_count(uint8_t out[]) - { - BOTAN_ASSERT_NOMSG(m_counter_size <= output_length()); - BOTAN_ASSERT_NOMSG(m_counter_size >= 8); - - const uint64_t bit_count = m_count * 8; - - if(m_count_big_endian) - store_be(bit_count, out + m_counter_size - 8); - else - store_le(bit_count, out + m_counter_size - 8); - } - + * MDx_HashFunction Constructor + */ +MDx_HashFunction::MDx_HashFunction(size_t block_len, bool byte_big_endian, bool bit_big_endian, + uint8_t cnt_size) + : m_pad_char(bit_big_endian == true ? 0x80 : 0x01), + m_counter_size(cnt_size), + m_block_bits(static_cast(ceil_log2(block_len))), + m_count_big_endian(byte_big_endian), + m_count(0), + m_buffer(block_len), + m_position(0) { + if (!is_power_of_2(block_len)) + throw Invalid_Argument("MDx_HashFunction block length must be a power of 2"); + if (m_block_bits < 3 || m_block_bits > 16) + throw Invalid_Argument("MDx_HashFunction block size too large or too small"); + if (m_counter_size < 8 || m_counter_size > block_len) + throw Invalid_State("MDx_HashFunction invalid counter length"); } -/* -* CBC Padding Methods -* (C) 1999-2007,2013,2018 Jack Lloyd -* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Clear memory of sensitive data + */ +void MDx_HashFunction::clear() { + zeroise(m_buffer); + m_count = m_position = 0; +} + +/* + * Update the hash + */ +void MDx_HashFunction::add_data(const uint8_t input[], size_t length) { + const size_t block_len = static_cast(1) << m_block_bits; + + m_count += length; + + if (m_position) { + buffer_insert(m_buffer, m_position, input, length); + + if (m_position + length >= block_len) { + compress_n(m_buffer.data(), 1); + input += (block_len - m_position); + length -= (block_len - m_position); + m_position = 0; + } + } + + // Just in case the compiler can't figure out block_len is a power of 2 + const size_t full_blocks = length >> m_block_bits; + const size_t remaining = length & (block_len - 1); + + if (full_blocks > 0) { + compress_n(input, full_blocks); + } + + buffer_insert(m_buffer, m_position, input + full_blocks * block_len, remaining); + m_position += remaining; +} + +/* + * Finalize a hash + */ +void MDx_HashFunction::final_result(uint8_t output[]) { + const size_t block_len = static_cast(1) << m_block_bits; + + clear_mem(&m_buffer[m_position], block_len - m_position); + m_buffer[m_position] = m_pad_char; + + if (m_position >= block_len - m_counter_size) { + compress_n(m_buffer.data(), 1); + zeroise(m_buffer); + } + + write_count(&m_buffer[block_len - m_counter_size]); + + compress_n(m_buffer.data(), 1); + copy_out(output); + clear(); +} + +/* + * Write the count bits to the buffer + */ +void MDx_HashFunction::write_count(uint8_t out[]) { + BOTAN_ASSERT_NOMSG(m_counter_size <= output_length()); + BOTAN_ASSERT_NOMSG(m_counter_size >= 8); + + const uint64_t bit_count = m_count * 8; + + if (m_count_big_endian) + store_be(bit_count, out + m_counter_size - 8); + else + store_le(bit_count, out + m_counter_size - 8); +} + +} // namespace Botan +/* + * CBC Padding Methods + * (C) 1999-2007,2013,2018 Jack Lloyd + * (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /** -* Get a block cipher padding method by name -*/ -BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) - { - if(algo_spec == "NoPadding") - return new Null_Padding; + * Get a block cipher padding method by name + */ +BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) { + if (algo_spec == "NoPadding") return new Null_Padding; - if(algo_spec == "PKCS7") - return new PKCS7_Padding; + if (algo_spec == "PKCS7") return new PKCS7_Padding; - if(algo_spec == "OneAndZeros") - return new OneAndZeros_Padding; + if (algo_spec == "OneAndZeros") return new OneAndZeros_Padding; - if(algo_spec == "X9.23") - return new ANSI_X923_Padding; - - if(algo_spec == "ESP") - return new ESP_Padding; - - return nullptr; - } - -/* -* Pad with PKCS #7 Method -*/ -void PKCS7_Padding::add_padding(secure_vector& buffer, - size_t last_byte_pos, - size_t block_size) const - { - const uint8_t pad_value = static_cast(block_size - last_byte_pos); - - for(size_t i = 0; i != pad_value; ++i) - buffer.push_back(pad_value); - } - -/* -* Unpad with PKCS #7 Method -*/ -size_t PKCS7_Padding::unpad(const uint8_t input[], size_t input_length) const - { - if(!valid_blocksize(input_length)) - return input_length; - - CT::poison(input, input_length); - - const uint8_t last_byte = input[input_length-1]; - - /* - The input should == the block size so if the last byte exceeds - that then the padding is certainly invalid - */ - auto bad_input = CT::Mask::is_gt(last_byte, input_length); - - const size_t pad_pos = input_length - last_byte; - - for(size_t i = 0; i != input_length - 1; ++i) - { - // Does this byte equal the expected pad byte? - const auto pad_eq = CT::Mask::is_equal(input[i], last_byte); - - // Ignore values that are not part of the padding - const auto in_range = CT::Mask::is_gte(i, pad_pos); - bad_input |= in_range & (~pad_eq); - } - - CT::unpoison(input, input_length); - - return bad_input.select_and_unpoison(input_length, pad_pos); - } - -/* -* Pad with ANSI X9.23 Method -*/ -void ANSI_X923_Padding::add_padding(secure_vector& buffer, - size_t last_byte_pos, - size_t block_size) const - { - const uint8_t pad_value = static_cast(block_size - last_byte_pos); - - for(size_t i = last_byte_pos; i < block_size-1; ++i) - { - buffer.push_back(0); - } - buffer.push_back(pad_value); - } - -/* -* Unpad with ANSI X9.23 Method -*/ -size_t ANSI_X923_Padding::unpad(const uint8_t input[], size_t input_length) const - { - if(!valid_blocksize(input_length)) - return input_length; - - CT::poison(input, input_length); - - const size_t last_byte = input[input_length-1]; - - auto bad_input = CT::Mask::is_gt(last_byte, input_length); - - const size_t pad_pos = input_length - last_byte; - - for(size_t i = 0; i != input_length - 1; ++i) - { - // Ignore values that are not part of the padding - const auto in_range = CT::Mask::is_gte(i, pad_pos); - const auto pad_is_nonzero = CT::Mask::expand(input[i]); - bad_input |= pad_is_nonzero & in_range; - } - - CT::unpoison(input, input_length); - - return bad_input.select_and_unpoison(input_length, pad_pos); - } - -/* -* Pad with One and Zeros Method -*/ -void OneAndZeros_Padding::add_padding(secure_vector& buffer, - size_t last_byte_pos, - size_t block_size) const - { - buffer.push_back(0x80); - - for(size_t i = last_byte_pos + 1; i % block_size; ++i) - buffer.push_back(0x00); - } - -/* -* Unpad with One and Zeros Method -*/ -size_t OneAndZeros_Padding::unpad(const uint8_t input[], size_t input_length) const - { - if(!valid_blocksize(input_length)) - return input_length; - - CT::poison(input, input_length); - - auto bad_input = CT::Mask::cleared(); - auto seen_0x80 = CT::Mask::cleared(); - - size_t pad_pos = input_length - 1; - size_t i = input_length; - - while(i) - { - const auto is_0x80 = CT::Mask::is_equal(input[i-1], 0x80); - const auto is_zero = CT::Mask::is_zero(input[i-1]); - - seen_0x80 |= is_0x80; - pad_pos -= seen_0x80.if_not_set_return(1); - bad_input |= ~seen_0x80 & ~is_zero; - i--; - } - bad_input |= ~seen_0x80; - - CT::unpoison(input, input_length); - - return CT::Mask::expand(bad_input).select_and_unpoison(input_length, pad_pos); - } - -/* -* Pad with ESP Padding Method -*/ -void ESP_Padding::add_padding(secure_vector& buffer, - size_t last_byte_pos, - size_t block_size) const - { - uint8_t pad_value = 0x01; - - for(size_t i = last_byte_pos; i < block_size; ++i) - { - buffer.push_back(pad_value++); - } - } - -/* -* Unpad with ESP Padding Method -*/ -size_t ESP_Padding::unpad(const uint8_t input[], size_t input_length) const - { - if(!valid_blocksize(input_length)) - return input_length; - - CT::poison(input, input_length); - - const uint8_t input_length_8 = static_cast(input_length); - const uint8_t last_byte = input[input_length-1]; - - auto bad_input = CT::Mask::is_zero(last_byte) | - CT::Mask::is_gt(last_byte, input_length_8); - - const uint8_t pad_pos = input_length_8 - last_byte; - size_t i = input_length_8 - 1; - while(i) - { - const auto in_range = CT::Mask::is_gt(i, pad_pos); - const auto incrementing = CT::Mask::is_equal(input[i-1], input[i]-1); - - bad_input |= CT::Mask(in_range) & ~incrementing; - --i; - } - - CT::unpoison(input, input_length); - return bad_input.select_and_unpoison(input_length_8, pad_pos); - } + if (algo_spec == "X9.23") return new ANSI_X923_Padding; + if (algo_spec == "ESP") return new ESP_Padding; + return nullptr; } -/* -* Cipher Modes -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Pad with PKCS #7 Method + */ +void PKCS7_Padding::add_padding(secure_vector& buffer, size_t last_byte_pos, + size_t block_size) const { + const uint8_t pad_value = static_cast(block_size - last_byte_pos); + + for (size_t i = 0; i != pad_value; ++i) buffer.push_back(pad_value); +} + +/* + * Unpad with PKCS #7 Method + */ +size_t PKCS7_Padding::unpad(const uint8_t input[], size_t input_length) const { + if (!valid_blocksize(input_length)) return input_length; + + CT::poison(input, input_length); + + const uint8_t last_byte = input[input_length - 1]; + + /* + The input should == the block size so if the last byte exceeds + that then the padding is certainly invalid + */ + auto bad_input = CT::Mask::is_gt(last_byte, input_length); + + const size_t pad_pos = input_length - last_byte; + + for (size_t i = 0; i != input_length - 1; ++i) { + // Does this byte equal the expected pad byte? + const auto pad_eq = CT::Mask::is_equal(input[i], last_byte); + + // Ignore values that are not part of the padding + const auto in_range = CT::Mask::is_gte(i, pad_pos); + bad_input |= in_range & (~pad_eq); + } + + CT::unpoison(input, input_length); + + return bad_input.select_and_unpoison(input_length, pad_pos); +} + +/* + * Pad with ANSI X9.23 Method + */ +void ANSI_X923_Padding::add_padding(secure_vector& buffer, size_t last_byte_pos, + size_t block_size) const { + const uint8_t pad_value = static_cast(block_size - last_byte_pos); + + for (size_t i = last_byte_pos; i < block_size - 1; ++i) { + buffer.push_back(0); + } + buffer.push_back(pad_value); +} + +/* + * Unpad with ANSI X9.23 Method + */ +size_t ANSI_X923_Padding::unpad(const uint8_t input[], size_t input_length) const { + if (!valid_blocksize(input_length)) return input_length; + + CT::poison(input, input_length); + + const size_t last_byte = input[input_length - 1]; + + auto bad_input = CT::Mask::is_gt(last_byte, input_length); + + const size_t pad_pos = input_length - last_byte; + + for (size_t i = 0; i != input_length - 1; ++i) { + // Ignore values that are not part of the padding + const auto in_range = CT::Mask::is_gte(i, pad_pos); + const auto pad_is_nonzero = CT::Mask::expand(input[i]); + bad_input |= pad_is_nonzero & in_range; + } + + CT::unpoison(input, input_length); + + return bad_input.select_and_unpoison(input_length, pad_pos); +} + +/* + * Pad with One and Zeros Method + */ +void OneAndZeros_Padding::add_padding(secure_vector& buffer, size_t last_byte_pos, + size_t block_size) const { + buffer.push_back(0x80); + + for (size_t i = last_byte_pos + 1; i % block_size; ++i) buffer.push_back(0x00); +} + +/* + * Unpad with One and Zeros Method + */ +size_t OneAndZeros_Padding::unpad(const uint8_t input[], size_t input_length) const { + if (!valid_blocksize(input_length)) return input_length; + + CT::poison(input, input_length); + + auto bad_input = CT::Mask::cleared(); + auto seen_0x80 = CT::Mask::cleared(); + + size_t pad_pos = input_length - 1; + size_t i = input_length; + + while (i) { + const auto is_0x80 = CT::Mask::is_equal(input[i - 1], 0x80); + const auto is_zero = CT::Mask::is_zero(input[i - 1]); + + seen_0x80 |= is_0x80; + pad_pos -= seen_0x80.if_not_set_return(1); + bad_input |= ~seen_0x80 & ~is_zero; + i--; + } + bad_input |= ~seen_0x80; + + CT::unpoison(input, input_length); + + return CT::Mask::expand(bad_input).select_and_unpoison(input_length, pad_pos); +} + +/* + * Pad with ESP Padding Method + */ +void ESP_Padding::add_padding(secure_vector& buffer, size_t last_byte_pos, + size_t block_size) const { + uint8_t pad_value = 0x01; + + for (size_t i = last_byte_pos; i < block_size; ++i) { + buffer.push_back(pad_value++); + } +} + +/* + * Unpad with ESP Padding Method + */ +size_t ESP_Padding::unpad(const uint8_t input[], size_t input_length) const { + if (!valid_blocksize(input_length)) return input_length; + + CT::poison(input, input_length); + + const uint8_t input_length_8 = static_cast(input_length); + const uint8_t last_byte = input[input_length - 1]; + + auto bad_input = + CT::Mask::is_zero(last_byte) | CT::Mask::is_gt(last_byte, input_length_8); + + const uint8_t pad_pos = input_length_8 - last_byte; + size_t i = input_length_8 - 1; + while (i) { + const auto in_range = CT::Mask::is_gt(i, pad_pos); + const auto incrementing = CT::Mask::is_equal(input[i - 1], input[i] - 1); + + bad_input |= CT::Mask(in_range) & ~incrementing; + --i; + } + + CT::unpoison(input, input_length); + return bad_input.select_and_unpoison(input_length_8, pad_pos); +} + +} // namespace Botan +/* + * Cipher Modes + * (C) 2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_BLOCK_CIPHER) #endif @@ -11600,2383 +9732,2588 @@ namespace Botan { std::unique_ptr Cipher_Mode::create_or_throw(const std::string& algo, Cipher_Dir direction, - const std::string& provider) - { - if(auto mode = Cipher_Mode::create(algo, direction, provider)) - return mode; + const std::string& provider) { + if (auto mode = Cipher_Mode::create(algo, direction, provider)) return mode; - throw Lookup_Error("Cipher mode", algo, provider); - } + throw Lookup_Error("Cipher mode", algo, provider); +} -std::unique_ptr Cipher_Mode::create(const std::string& algo, - Cipher_Dir direction, - const std::string& provider) - { +std::unique_ptr Cipher_Mode::create(const std::string& algo, Cipher_Dir direction, + const std::string& provider) { #if defined(BOTAN_HAS_COMMONCRYPTO) - if(provider.empty() || provider == "commoncrypto") - { - std::unique_ptr commoncrypto_cipher(make_commoncrypto_cipher_mode(algo, direction)); + if (provider.empty() || provider == "commoncrypto") { + std::unique_ptr commoncrypto_cipher( + make_commoncrypto_cipher_mode(algo, direction)); - if(commoncrypto_cipher) - return commoncrypto_cipher; + if (commoncrypto_cipher) return commoncrypto_cipher; - if(!provider.empty()) - return std::unique_ptr(); - } + if (!provider.empty()) return std::unique_ptr(); + } #endif #if defined(BOTAN_HAS_OPENSSL) - if(provider.empty() || provider == "openssl") - { - std::unique_ptr openssl_cipher(make_openssl_cipher_mode(algo, direction)); + if (provider.empty() || provider == "openssl") { + std::unique_ptr openssl_cipher(make_openssl_cipher_mode(algo, direction)); - if(openssl_cipher) - return openssl_cipher; + if (openssl_cipher) return openssl_cipher; - if(!provider.empty()) - return std::unique_ptr(); - } + if (!provider.empty()) return std::unique_ptr(); + } #endif #if defined(BOTAN_HAS_STREAM_CIPHER) - if(auto sc = StreamCipher::create(algo)) - { - return std::unique_ptr(new Stream_Cipher_Mode(sc.release())); - } + if (auto sc = StreamCipher::create(algo)) { + return std::unique_ptr(new Stream_Cipher_Mode(sc.release())); + } #endif #if defined(BOTAN_HAS_AEAD_MODES) - if(auto aead = AEAD_Mode::create(algo, direction)) - { - return std::unique_ptr(aead.release()); - } + if (auto aead = AEAD_Mode::create(algo, direction)) { + return std::unique_ptr(aead.release()); + } #endif - if(algo.find('/') != std::string::npos) - { - const std::vector algo_parts = split_on(algo, '/'); - const std::string cipher_name = algo_parts[0]; - const std::vector mode_info = parse_algorithm_name(algo_parts[1]); + if (algo.find('/') != std::string::npos) { + const std::vector algo_parts = split_on(algo, '/'); + const std::string cipher_name = algo_parts[0]; + const std::vector mode_info = parse_algorithm_name(algo_parts[1]); - if(mode_info.empty()) - return std::unique_ptr(); + if (mode_info.empty()) return std::unique_ptr(); - std::ostringstream alg_args; + std::ostringstream alg_args; - alg_args << '(' << cipher_name; - for(size_t i = 1; i < mode_info.size(); ++i) - alg_args << ',' << mode_info[i]; - for(size_t i = 2; i < algo_parts.size(); ++i) - alg_args << ',' << algo_parts[i]; - alg_args << ')'; + alg_args << '(' << cipher_name; + for (size_t i = 1; i < mode_info.size(); ++i) alg_args << ',' << mode_info[i]; + for (size_t i = 2; i < algo_parts.size(); ++i) alg_args << ',' << algo_parts[i]; + alg_args << ')'; - const std::string mode_name = mode_info[0] + alg_args.str(); - return Cipher_Mode::create(mode_name, direction, provider); - } + const std::string mode_name = mode_info[0] + alg_args.str(); + return Cipher_Mode::create(mode_name, direction, provider); + } #if defined(BOTAN_HAS_BLOCK_CIPHER) - SCAN_Name spec(algo); + SCAN_Name spec(algo); - if(spec.arg_count() == 0) - { - return std::unique_ptr(); - } + if (spec.arg_count() == 0) { + return std::unique_ptr(); + } - std::unique_ptr bc(BlockCipher::create(spec.arg(0), provider)); + std::unique_ptr bc(BlockCipher::create(spec.arg(0), provider)); - if(!bc) - { - return std::unique_ptr(); - } + if (!bc) { + return std::unique_ptr(); + } #if defined(BOTAN_HAS_MODE_CBC) - if(spec.algo_name() == "CBC") - { - const std::string padding = spec.arg(1, "PKCS7"); + if (spec.algo_name() == "CBC") { + const std::string padding = spec.arg(1, "PKCS7"); - if(padding == "CTS") - { - if(direction == ENCRYPTION) - return std::unique_ptr(new CTS_Encryption(bc.release())); - else - return std::unique_ptr(new CTS_Decryption(bc.release())); - } - else - { - std::unique_ptr pad(get_bc_pad(padding)); - - if(pad) - { - if(direction == ENCRYPTION) - return std::unique_ptr(new CBC_Encryption(bc.release(), pad.release())); + if (padding == "CTS") { + if (direction == ENCRYPTION) + return std::unique_ptr(new CTS_Encryption(bc.release())); else - return std::unique_ptr(new CBC_Decryption(bc.release(), pad.release())); + return std::unique_ptr(new CTS_Decryption(bc.release())); + } else { + std::unique_ptr pad(get_bc_pad(padding)); + + if (pad) { + if (direction == ENCRYPTION) + return std::unique_ptr( + new CBC_Encryption(bc.release(), pad.release())); + else + return std::unique_ptr( + new CBC_Decryption(bc.release(), pad.release())); } - } - } + } + } #endif #if defined(BOTAN_HAS_MODE_XTS) - if(spec.algo_name() == "XTS") - { - if(direction == ENCRYPTION) - return std::unique_ptr(new XTS_Encryption(bc.release())); - else - return std::unique_ptr(new XTS_Decryption(bc.release())); - } + if (spec.algo_name() == "XTS") { + if (direction == ENCRYPTION) + return std::unique_ptr(new XTS_Encryption(bc.release())); + else + return std::unique_ptr(new XTS_Decryption(bc.release())); + } #endif #if defined(BOTAN_HAS_MODE_CFB) - if(spec.algo_name() == "CFB") - { - const size_t feedback_bits = spec.arg_as_integer(1, 8*bc->block_size()); - if(direction == ENCRYPTION) - return std::unique_ptr(new CFB_Encryption(bc.release(), feedback_bits)); - else - return std::unique_ptr(new CFB_Decryption(bc.release(), feedback_bits)); - } + if (spec.algo_name() == "CFB") { + const size_t feedback_bits = spec.arg_as_integer(1, 8 * bc->block_size()); + if (direction == ENCRYPTION) + return std::unique_ptr(new CFB_Encryption(bc.release(), feedback_bits)); + else + return std::unique_ptr(new CFB_Decryption(bc.release(), feedback_bits)); + } #endif #endif - return std::unique_ptr(); - } - -//static -std::vector Cipher_Mode::providers(const std::string& algo_spec) - { - const std::vector& possible = { "base", "openssl", "commoncrypto" }; - std::vector providers; - for(auto&& prov : possible) - { - std::unique_ptr mode = Cipher_Mode::create(algo_spec, ENCRYPTION, prov); - if(mode) - { - providers.push_back(prov); // available - } - } - return providers; - } - + return std::unique_ptr(); } -/* -* Comba Multiplication and Squaring -* -* This file was automatically generated by ./src/scripts/comba.py on 2018-05-08 -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +// static +std::vector Cipher_Mode::providers(const std::string& algo_spec) { + const std::vector& possible = {"base", "openssl", "commoncrypto"}; + std::vector providers; + for (auto&& prov : possible) { + std::unique_ptr mode = Cipher_Mode::create(algo_spec, ENCRYPTION, prov); + if (mode) { + providers.push_back(prov); // available + } + } + return providers; +} + +} // namespace Botan +/* + * Comba Multiplication and Squaring + * + * This file was automatically generated by ./src/scripts/comba.py on 2018-05-08 + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Comba 4x4 Squaring -*/ -void bigint_comba_sqr4(word z[8], const word x[4]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; - z[ 7] = w1; - } - -/* -* Comba 4x4 Multiplication -*/ -void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - z[ 6] = w0; - z[ 7] = w1; - } - -/* -* Comba 6x6 Squaring -*/ -void bigint_comba_sqr6(word z[12], const word x[6]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); - word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); - z[ 7] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); - word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); - z[ 8] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = 0; - - word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); - z[10] = w1; - z[11] = w2; - } - -/* -* Comba 6x6 Multiplication -*/ -void bigint_comba_mul6(word z[12], const word x[6], const word y[6]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); - z[ 6] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); - z[ 7] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); - z[ 8] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); - z[10] = w1; - z[11] = w2; - } - -/* -* Comba 8x8 Squaring -*/ -void bigint_comba_sqr8(word z[16], const word x[8]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); - word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); - z[ 7] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); - word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); - z[ 8] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); - word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); - z[10] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); - z[11] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); - word3_muladd (&w2, &w1, &w0, x[ 6], x[ 6]); - z[12] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); - z[13] = w1; w1 = 0; - - word3_muladd (&w1, &w0, &w2, x[ 7], x[ 7]); - z[14] = w2; - z[15] = w0; - } - -/* -* Comba 8x8 Multiplication -*/ -void bigint_comba_mul8(word z[16], const word x[8], const word y[8]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); - z[ 6] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); - z[ 7] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); - z[ 8] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); - z[10] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); - z[11] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); - z[12] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); - z[13] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); - z[14] = w2; - z[15] = w0; - } - -/* -* Comba 9x9 Squaring -*/ -void bigint_comba_sqr9(word z[18], const word x[9]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); - word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); - z[ 7] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); - word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); - z[ 8] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); - word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); - z[10] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); - z[11] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); - word3_muladd (&w2, &w1, &w0, x[ 6], x[ 6]); - z[12] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); - z[13] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]); - word3_muladd (&w1, &w0, &w2, x[ 7], x[ 7]); - z[14] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]); - z[15] = w0; w0 = 0; - - word3_muladd (&w0, &w2, &w1, x[ 8], x[ 8]); - z[16] = w1; - z[17] = w2; - } - -/* -* Comba 9x9 Multiplication -*/ -void bigint_comba_mul9(word z[18], const word x[9], const word y[9]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); - z[ 6] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); - z[ 7] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]); - z[ 8] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]); - z[10] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]); - z[11] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]); - z[12] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]); - z[13] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]); - z[14] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]); - z[15] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]); - z[16] = w1; - z[17] = w2; - } - -/* -* Comba 16x16 Squaring -*/ -void bigint_comba_sqr16(word z[32], const word x[16]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); - word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); - z[ 7] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); - word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); - z[ 8] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 9]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); - word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); - z[10] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 9]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); - z[11] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); - word3_muladd (&w2, &w1, &w0, x[ 6], x[ 6]); - z[12] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 9]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); - z[13] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 9]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]); - word3_muladd (&w1, &w0, &w2, x[ 7], x[ 7]); - z[14] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]); - z[15] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[ 9]); - word3_muladd (&w0, &w2, &w1, x[ 8], x[ 8]); - z[16] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[ 9]); - z[17] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[10]); - word3_muladd (&w2, &w1, &w0, x[ 9], x[ 9]); - z[18] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[10]); - z[19] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[11]); - word3_muladd (&w1, &w0, &w2, x[10], x[10]); - z[20] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[11]); - z[21] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[10], x[12]); - word3_muladd (&w0, &w2, &w1, x[11], x[11]); - z[22] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[10], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[11], x[12]); - z[23] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[11], x[13]); - word3_muladd (&w2, &w1, &w0, x[12], x[12]); - z[24] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[10], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[11], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[12], x[13]); - z[25] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[11], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[12], x[14]); - word3_muladd (&w1, &w0, &w2, x[13], x[13]); - z[26] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[12], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[13], x[14]); - z[27] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[13], x[15]); - word3_muladd (&w0, &w2, &w1, x[14], x[14]); - z[28] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[14], x[15]); - z[29] = w2; w2 = 0; - - word3_muladd (&w2, &w1, &w0, x[15], x[15]); - z[30] = w0; - z[31] = w1; - } - -/* -* Comba 16x16 Multiplication -*/ -void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); - z[ 6] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); - z[ 7] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]); - z[ 8] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 0]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 0]); - z[10] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 0]); - z[11] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 0]); - z[12] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 0]); - z[13] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 0]); - z[14] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 0]); - z[15] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 1], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 1]); - z[16] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 2], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 2]); - z[17] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 3], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 3]); - z[18] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 4], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[10]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 4]); - z[19] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 5], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[11]); - word3_muladd(&w1, &w0, &w2, x[10], y[10]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 5]); - z[20] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 6], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[12]); - word3_muladd(&w2, &w1, &w0, x[10], y[11]); - word3_muladd(&w2, &w1, &w0, x[11], y[10]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 6]); - z[21] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 7], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[13]); - word3_muladd(&w0, &w2, &w1, x[10], y[12]); - word3_muladd(&w0, &w2, &w1, x[11], y[11]); - word3_muladd(&w0, &w2, &w1, x[12], y[10]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 7]); - z[22] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 8], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[14]); - word3_muladd(&w1, &w0, &w2, x[10], y[13]); - word3_muladd(&w1, &w0, &w2, x[11], y[12]); - word3_muladd(&w1, &w0, &w2, x[12], y[11]); - word3_muladd(&w1, &w0, &w2, x[13], y[10]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 8]); - z[23] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 9], y[15]); - word3_muladd(&w2, &w1, &w0, x[10], y[14]); - word3_muladd(&w2, &w1, &w0, x[11], y[13]); - word3_muladd(&w2, &w1, &w0, x[12], y[12]); - word3_muladd(&w2, &w1, &w0, x[13], y[11]); - word3_muladd(&w2, &w1, &w0, x[14], y[10]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 9]); - z[24] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[10], y[15]); - word3_muladd(&w0, &w2, &w1, x[11], y[14]); - word3_muladd(&w0, &w2, &w1, x[12], y[13]); - word3_muladd(&w0, &w2, &w1, x[13], y[12]); - word3_muladd(&w0, &w2, &w1, x[14], y[11]); - word3_muladd(&w0, &w2, &w1, x[15], y[10]); - z[25] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[11], y[15]); - word3_muladd(&w1, &w0, &w2, x[12], y[14]); - word3_muladd(&w1, &w0, &w2, x[13], y[13]); - word3_muladd(&w1, &w0, &w2, x[14], y[12]); - word3_muladd(&w1, &w0, &w2, x[15], y[11]); - z[26] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[12], y[15]); - word3_muladd(&w2, &w1, &w0, x[13], y[14]); - word3_muladd(&w2, &w1, &w0, x[14], y[13]); - word3_muladd(&w2, &w1, &w0, x[15], y[12]); - z[27] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[13], y[15]); - word3_muladd(&w0, &w2, &w1, x[14], y[14]); - word3_muladd(&w0, &w2, &w1, x[15], y[13]); - z[28] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[14], y[15]); - word3_muladd(&w1, &w0, &w2, x[15], y[14]); - z[29] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[15], y[15]); - z[30] = w0; - z[31] = w1; - } - -/* -* Comba 24x24 Squaring -*/ -void bigint_comba_sqr24(word z[48], const word x[24]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); - word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); - z[ 7] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); - word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); - z[ 8] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 9]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); - word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); - z[10] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 9]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); - z[11] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); - word3_muladd (&w2, &w1, &w0, x[ 6], x[ 6]); - z[12] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 9]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); - z[13] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 9]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]); - word3_muladd (&w1, &w0, &w2, x[ 7], x[ 7]); - z[14] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]); - z[15] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[16]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[ 9]); - word3_muladd (&w0, &w2, &w1, x[ 8], x[ 8]); - z[16] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[17]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[16]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[ 9]); - z[17] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[18]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[17]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[16]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[10]); - word3_muladd (&w2, &w1, &w0, x[ 9], x[ 9]); - z[18] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[19]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[18]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[17]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[16]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[10]); - z[19] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[20]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[19]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[18]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[17]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[16]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[11]); - word3_muladd (&w1, &w0, &w2, x[10], x[10]); - z[20] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[21]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[20]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[19]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[18]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[17]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[16]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[11]); - z[21] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[22]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[21]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[20]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[19]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[18]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[17]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[16]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[10], x[12]); - word3_muladd (&w0, &w2, &w1, x[11], x[11]); - z[22] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[23]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[22]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[21]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[20]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[19]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[18]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[17]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[16]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[10], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[11], x[12]); - z[23] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[23]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[22]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[21]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[20]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[19]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[18]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[17]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[16]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[11], x[13]); - word3_muladd (&w2, &w1, &w0, x[12], x[12]); - z[24] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[23]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[22]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[21]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[20]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[19]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[18]); - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[17]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[16]); - word3_muladd_2(&w0, &w2, &w1, x[10], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[11], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[12], x[13]); - z[25] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[23]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[22]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[21]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[20]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[19]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[18]); - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[17]); - word3_muladd_2(&w1, &w0, &w2, x[10], x[16]); - word3_muladd_2(&w1, &w0, &w2, x[11], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[12], x[14]); - word3_muladd (&w1, &w0, &w2, x[13], x[13]); - z[26] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[23]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[22]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[21]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[20]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[19]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[18]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[17]); - word3_muladd_2(&w2, &w1, &w0, x[11], x[16]); - word3_muladd_2(&w2, &w1, &w0, x[12], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[13], x[14]); - z[27] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[23]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[22]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[21]); - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[20]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[19]); - word3_muladd_2(&w0, &w2, &w1, x[10], x[18]); - word3_muladd_2(&w0, &w2, &w1, x[11], x[17]); - word3_muladd_2(&w0, &w2, &w1, x[12], x[16]); - word3_muladd_2(&w0, &w2, &w1, x[13], x[15]); - word3_muladd (&w0, &w2, &w1, x[14], x[14]); - z[28] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[23]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[22]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[21]); - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[20]); - word3_muladd_2(&w1, &w0, &w2, x[10], x[19]); - word3_muladd_2(&w1, &w0, &w2, x[11], x[18]); - word3_muladd_2(&w1, &w0, &w2, x[12], x[17]); - word3_muladd_2(&w1, &w0, &w2, x[13], x[16]); - word3_muladd_2(&w1, &w0, &w2, x[14], x[15]); - z[29] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[23]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[22]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[21]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[20]); - word3_muladd_2(&w2, &w1, &w0, x[11], x[19]); - word3_muladd_2(&w2, &w1, &w0, x[12], x[18]); - word3_muladd_2(&w2, &w1, &w0, x[13], x[17]); - word3_muladd_2(&w2, &w1, &w0, x[14], x[16]); - word3_muladd (&w2, &w1, &w0, x[15], x[15]); - z[30] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[23]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[22]); - word3_muladd_2(&w0, &w2, &w1, x[10], x[21]); - word3_muladd_2(&w0, &w2, &w1, x[11], x[20]); - word3_muladd_2(&w0, &w2, &w1, x[12], x[19]); - word3_muladd_2(&w0, &w2, &w1, x[13], x[18]); - word3_muladd_2(&w0, &w2, &w1, x[14], x[17]); - word3_muladd_2(&w0, &w2, &w1, x[15], x[16]); - z[31] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[23]); - word3_muladd_2(&w1, &w0, &w2, x[10], x[22]); - word3_muladd_2(&w1, &w0, &w2, x[11], x[21]); - word3_muladd_2(&w1, &w0, &w2, x[12], x[20]); - word3_muladd_2(&w1, &w0, &w2, x[13], x[19]); - word3_muladd_2(&w1, &w0, &w2, x[14], x[18]); - word3_muladd_2(&w1, &w0, &w2, x[15], x[17]); - word3_muladd (&w1, &w0, &w2, x[16], x[16]); - z[32] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[10], x[23]); - word3_muladd_2(&w2, &w1, &w0, x[11], x[22]); - word3_muladd_2(&w2, &w1, &w0, x[12], x[21]); - word3_muladd_2(&w2, &w1, &w0, x[13], x[20]); - word3_muladd_2(&w2, &w1, &w0, x[14], x[19]); - word3_muladd_2(&w2, &w1, &w0, x[15], x[18]); - word3_muladd_2(&w2, &w1, &w0, x[16], x[17]); - z[33] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[11], x[23]); - word3_muladd_2(&w0, &w2, &w1, x[12], x[22]); - word3_muladd_2(&w0, &w2, &w1, x[13], x[21]); - word3_muladd_2(&w0, &w2, &w1, x[14], x[20]); - word3_muladd_2(&w0, &w2, &w1, x[15], x[19]); - word3_muladd_2(&w0, &w2, &w1, x[16], x[18]); - word3_muladd (&w0, &w2, &w1, x[17], x[17]); - z[34] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[12], x[23]); - word3_muladd_2(&w1, &w0, &w2, x[13], x[22]); - word3_muladd_2(&w1, &w0, &w2, x[14], x[21]); - word3_muladd_2(&w1, &w0, &w2, x[15], x[20]); - word3_muladd_2(&w1, &w0, &w2, x[16], x[19]); - word3_muladd_2(&w1, &w0, &w2, x[17], x[18]); - z[35] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[13], x[23]); - word3_muladd_2(&w2, &w1, &w0, x[14], x[22]); - word3_muladd_2(&w2, &w1, &w0, x[15], x[21]); - word3_muladd_2(&w2, &w1, &w0, x[16], x[20]); - word3_muladd_2(&w2, &w1, &w0, x[17], x[19]); - word3_muladd (&w2, &w1, &w0, x[18], x[18]); - z[36] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[14], x[23]); - word3_muladd_2(&w0, &w2, &w1, x[15], x[22]); - word3_muladd_2(&w0, &w2, &w1, x[16], x[21]); - word3_muladd_2(&w0, &w2, &w1, x[17], x[20]); - word3_muladd_2(&w0, &w2, &w1, x[18], x[19]); - z[37] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[15], x[23]); - word3_muladd_2(&w1, &w0, &w2, x[16], x[22]); - word3_muladd_2(&w1, &w0, &w2, x[17], x[21]); - word3_muladd_2(&w1, &w0, &w2, x[18], x[20]); - word3_muladd (&w1, &w0, &w2, x[19], x[19]); - z[38] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[16], x[23]); - word3_muladd_2(&w2, &w1, &w0, x[17], x[22]); - word3_muladd_2(&w2, &w1, &w0, x[18], x[21]); - word3_muladd_2(&w2, &w1, &w0, x[19], x[20]); - z[39] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[17], x[23]); - word3_muladd_2(&w0, &w2, &w1, x[18], x[22]); - word3_muladd_2(&w0, &w2, &w1, x[19], x[21]); - word3_muladd (&w0, &w2, &w1, x[20], x[20]); - z[40] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[18], x[23]); - word3_muladd_2(&w1, &w0, &w2, x[19], x[22]); - word3_muladd_2(&w1, &w0, &w2, x[20], x[21]); - z[41] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[19], x[23]); - word3_muladd_2(&w2, &w1, &w0, x[20], x[22]); - word3_muladd (&w2, &w1, &w0, x[21], x[21]); - z[42] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[20], x[23]); - word3_muladd_2(&w0, &w2, &w1, x[21], x[22]); - z[43] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[21], x[23]); - word3_muladd (&w1, &w0, &w2, x[22], x[22]); - z[44] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[22], x[23]); - z[45] = w0; w0 = 0; - - word3_muladd (&w0, &w2, &w1, x[23], x[23]); - z[46] = w1; - z[47] = w2; - } - -/* -* Comba 24x24 Multiplication -*/ -void bigint_comba_mul24(word z[48], const word x[24], const word y[24]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); - z[ 6] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); - z[ 7] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]); - z[ 8] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 0]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 0]); - z[10] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 0]); - z[11] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 0]); - z[12] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 0]); - z[13] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 0]); - z[14] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 0]); - z[15] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[16]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[16], y[ 0]); - z[16] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[17]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[16]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[16], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[17], y[ 0]); - z[17] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[18]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[17]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[16]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[16], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[17], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[18], y[ 0]); - z[18] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[19]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[18]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[17]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[16]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[10]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[16], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[17], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[18], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[19], y[ 0]); - z[19] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[20]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[19]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[18]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[17]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[16]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[11]); - word3_muladd(&w1, &w0, &w2, x[10], y[10]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[16], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[17], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[18], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[19], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[20], y[ 0]); - z[20] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[21]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[20]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[19]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[18]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[17]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[16]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[12]); - word3_muladd(&w2, &w1, &w0, x[10], y[11]); - word3_muladd(&w2, &w1, &w0, x[11], y[10]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[16], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[17], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[18], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[19], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[20], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[21], y[ 0]); - z[21] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[22]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[21]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[20]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[19]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[18]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[17]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[16]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[13]); - word3_muladd(&w0, &w2, &w1, x[10], y[12]); - word3_muladd(&w0, &w2, &w1, x[11], y[11]); - word3_muladd(&w0, &w2, &w1, x[12], y[10]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[16], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[17], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[18], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[19], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[20], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[21], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[22], y[ 0]); - z[22] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[23]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[22]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[21]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[20]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[19]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[18]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[17]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[16]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[14]); - word3_muladd(&w1, &w0, &w2, x[10], y[13]); - word3_muladd(&w1, &w0, &w2, x[11], y[12]); - word3_muladd(&w1, &w0, &w2, x[12], y[11]); - word3_muladd(&w1, &w0, &w2, x[13], y[10]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[16], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[17], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[18], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[19], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[20], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[21], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[22], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[23], y[ 0]); - z[23] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 1], y[23]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[22]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[21]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[20]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[19]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[18]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[17]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[16]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[15]); - word3_muladd(&w2, &w1, &w0, x[10], y[14]); - word3_muladd(&w2, &w1, &w0, x[11], y[13]); - word3_muladd(&w2, &w1, &w0, x[12], y[12]); - word3_muladd(&w2, &w1, &w0, x[13], y[11]); - word3_muladd(&w2, &w1, &w0, x[14], y[10]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[16], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[17], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[18], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[19], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[20], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[21], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[22], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[23], y[ 1]); - z[24] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 2], y[23]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[22]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[21]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[20]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[19]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[18]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[17]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[16]); - word3_muladd(&w0, &w2, &w1, x[10], y[15]); - word3_muladd(&w0, &w2, &w1, x[11], y[14]); - word3_muladd(&w0, &w2, &w1, x[12], y[13]); - word3_muladd(&w0, &w2, &w1, x[13], y[12]); - word3_muladd(&w0, &w2, &w1, x[14], y[11]); - word3_muladd(&w0, &w2, &w1, x[15], y[10]); - word3_muladd(&w0, &w2, &w1, x[16], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[17], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[18], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[19], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[20], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[21], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[22], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[23], y[ 2]); - z[25] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 3], y[23]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[22]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[21]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[20]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[19]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[18]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[17]); - word3_muladd(&w1, &w0, &w2, x[10], y[16]); - word3_muladd(&w1, &w0, &w2, x[11], y[15]); - word3_muladd(&w1, &w0, &w2, x[12], y[14]); - word3_muladd(&w1, &w0, &w2, x[13], y[13]); - word3_muladd(&w1, &w0, &w2, x[14], y[12]); - word3_muladd(&w1, &w0, &w2, x[15], y[11]); - word3_muladd(&w1, &w0, &w2, x[16], y[10]); - word3_muladd(&w1, &w0, &w2, x[17], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[18], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[19], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[20], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[21], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[22], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[23], y[ 3]); - z[26] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 4], y[23]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[22]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[21]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[20]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[19]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[18]); - word3_muladd(&w2, &w1, &w0, x[10], y[17]); - word3_muladd(&w2, &w1, &w0, x[11], y[16]); - word3_muladd(&w2, &w1, &w0, x[12], y[15]); - word3_muladd(&w2, &w1, &w0, x[13], y[14]); - word3_muladd(&w2, &w1, &w0, x[14], y[13]); - word3_muladd(&w2, &w1, &w0, x[15], y[12]); - word3_muladd(&w2, &w1, &w0, x[16], y[11]); - word3_muladd(&w2, &w1, &w0, x[17], y[10]); - word3_muladd(&w2, &w1, &w0, x[18], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[19], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[20], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[21], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[22], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[23], y[ 4]); - z[27] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 5], y[23]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[22]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[21]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[20]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[19]); - word3_muladd(&w0, &w2, &w1, x[10], y[18]); - word3_muladd(&w0, &w2, &w1, x[11], y[17]); - word3_muladd(&w0, &w2, &w1, x[12], y[16]); - word3_muladd(&w0, &w2, &w1, x[13], y[15]); - word3_muladd(&w0, &w2, &w1, x[14], y[14]); - word3_muladd(&w0, &w2, &w1, x[15], y[13]); - word3_muladd(&w0, &w2, &w1, x[16], y[12]); - word3_muladd(&w0, &w2, &w1, x[17], y[11]); - word3_muladd(&w0, &w2, &w1, x[18], y[10]); - word3_muladd(&w0, &w2, &w1, x[19], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[20], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[21], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[22], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[23], y[ 5]); - z[28] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 6], y[23]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[22]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[21]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[20]); - word3_muladd(&w1, &w0, &w2, x[10], y[19]); - word3_muladd(&w1, &w0, &w2, x[11], y[18]); - word3_muladd(&w1, &w0, &w2, x[12], y[17]); - word3_muladd(&w1, &w0, &w2, x[13], y[16]); - word3_muladd(&w1, &w0, &w2, x[14], y[15]); - word3_muladd(&w1, &w0, &w2, x[15], y[14]); - word3_muladd(&w1, &w0, &w2, x[16], y[13]); - word3_muladd(&w1, &w0, &w2, x[17], y[12]); - word3_muladd(&w1, &w0, &w2, x[18], y[11]); - word3_muladd(&w1, &w0, &w2, x[19], y[10]); - word3_muladd(&w1, &w0, &w2, x[20], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[21], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[22], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[23], y[ 6]); - z[29] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 7], y[23]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[22]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[21]); - word3_muladd(&w2, &w1, &w0, x[10], y[20]); - word3_muladd(&w2, &w1, &w0, x[11], y[19]); - word3_muladd(&w2, &w1, &w0, x[12], y[18]); - word3_muladd(&w2, &w1, &w0, x[13], y[17]); - word3_muladd(&w2, &w1, &w0, x[14], y[16]); - word3_muladd(&w2, &w1, &w0, x[15], y[15]); - word3_muladd(&w2, &w1, &w0, x[16], y[14]); - word3_muladd(&w2, &w1, &w0, x[17], y[13]); - word3_muladd(&w2, &w1, &w0, x[18], y[12]); - word3_muladd(&w2, &w1, &w0, x[19], y[11]); - word3_muladd(&w2, &w1, &w0, x[20], y[10]); - word3_muladd(&w2, &w1, &w0, x[21], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[22], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[23], y[ 7]); - z[30] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 8], y[23]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[22]); - word3_muladd(&w0, &w2, &w1, x[10], y[21]); - word3_muladd(&w0, &w2, &w1, x[11], y[20]); - word3_muladd(&w0, &w2, &w1, x[12], y[19]); - word3_muladd(&w0, &w2, &w1, x[13], y[18]); - word3_muladd(&w0, &w2, &w1, x[14], y[17]); - word3_muladd(&w0, &w2, &w1, x[15], y[16]); - word3_muladd(&w0, &w2, &w1, x[16], y[15]); - word3_muladd(&w0, &w2, &w1, x[17], y[14]); - word3_muladd(&w0, &w2, &w1, x[18], y[13]); - word3_muladd(&w0, &w2, &w1, x[19], y[12]); - word3_muladd(&w0, &w2, &w1, x[20], y[11]); - word3_muladd(&w0, &w2, &w1, x[21], y[10]); - word3_muladd(&w0, &w2, &w1, x[22], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[23], y[ 8]); - z[31] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 9], y[23]); - word3_muladd(&w1, &w0, &w2, x[10], y[22]); - word3_muladd(&w1, &w0, &w2, x[11], y[21]); - word3_muladd(&w1, &w0, &w2, x[12], y[20]); - word3_muladd(&w1, &w0, &w2, x[13], y[19]); - word3_muladd(&w1, &w0, &w2, x[14], y[18]); - word3_muladd(&w1, &w0, &w2, x[15], y[17]); - word3_muladd(&w1, &w0, &w2, x[16], y[16]); - word3_muladd(&w1, &w0, &w2, x[17], y[15]); - word3_muladd(&w1, &w0, &w2, x[18], y[14]); - word3_muladd(&w1, &w0, &w2, x[19], y[13]); - word3_muladd(&w1, &w0, &w2, x[20], y[12]); - word3_muladd(&w1, &w0, &w2, x[21], y[11]); - word3_muladd(&w1, &w0, &w2, x[22], y[10]); - word3_muladd(&w1, &w0, &w2, x[23], y[ 9]); - z[32] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[10], y[23]); - word3_muladd(&w2, &w1, &w0, x[11], y[22]); - word3_muladd(&w2, &w1, &w0, x[12], y[21]); - word3_muladd(&w2, &w1, &w0, x[13], y[20]); - word3_muladd(&w2, &w1, &w0, x[14], y[19]); - word3_muladd(&w2, &w1, &w0, x[15], y[18]); - word3_muladd(&w2, &w1, &w0, x[16], y[17]); - word3_muladd(&w2, &w1, &w0, x[17], y[16]); - word3_muladd(&w2, &w1, &w0, x[18], y[15]); - word3_muladd(&w2, &w1, &w0, x[19], y[14]); - word3_muladd(&w2, &w1, &w0, x[20], y[13]); - word3_muladd(&w2, &w1, &w0, x[21], y[12]); - word3_muladd(&w2, &w1, &w0, x[22], y[11]); - word3_muladd(&w2, &w1, &w0, x[23], y[10]); - z[33] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[11], y[23]); - word3_muladd(&w0, &w2, &w1, x[12], y[22]); - word3_muladd(&w0, &w2, &w1, x[13], y[21]); - word3_muladd(&w0, &w2, &w1, x[14], y[20]); - word3_muladd(&w0, &w2, &w1, x[15], y[19]); - word3_muladd(&w0, &w2, &w1, x[16], y[18]); - word3_muladd(&w0, &w2, &w1, x[17], y[17]); - word3_muladd(&w0, &w2, &w1, x[18], y[16]); - word3_muladd(&w0, &w2, &w1, x[19], y[15]); - word3_muladd(&w0, &w2, &w1, x[20], y[14]); - word3_muladd(&w0, &w2, &w1, x[21], y[13]); - word3_muladd(&w0, &w2, &w1, x[22], y[12]); - word3_muladd(&w0, &w2, &w1, x[23], y[11]); - z[34] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[12], y[23]); - word3_muladd(&w1, &w0, &w2, x[13], y[22]); - word3_muladd(&w1, &w0, &w2, x[14], y[21]); - word3_muladd(&w1, &w0, &w2, x[15], y[20]); - word3_muladd(&w1, &w0, &w2, x[16], y[19]); - word3_muladd(&w1, &w0, &w2, x[17], y[18]); - word3_muladd(&w1, &w0, &w2, x[18], y[17]); - word3_muladd(&w1, &w0, &w2, x[19], y[16]); - word3_muladd(&w1, &w0, &w2, x[20], y[15]); - word3_muladd(&w1, &w0, &w2, x[21], y[14]); - word3_muladd(&w1, &w0, &w2, x[22], y[13]); - word3_muladd(&w1, &w0, &w2, x[23], y[12]); - z[35] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[13], y[23]); - word3_muladd(&w2, &w1, &w0, x[14], y[22]); - word3_muladd(&w2, &w1, &w0, x[15], y[21]); - word3_muladd(&w2, &w1, &w0, x[16], y[20]); - word3_muladd(&w2, &w1, &w0, x[17], y[19]); - word3_muladd(&w2, &w1, &w0, x[18], y[18]); - word3_muladd(&w2, &w1, &w0, x[19], y[17]); - word3_muladd(&w2, &w1, &w0, x[20], y[16]); - word3_muladd(&w2, &w1, &w0, x[21], y[15]); - word3_muladd(&w2, &w1, &w0, x[22], y[14]); - word3_muladd(&w2, &w1, &w0, x[23], y[13]); - z[36] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[14], y[23]); - word3_muladd(&w0, &w2, &w1, x[15], y[22]); - word3_muladd(&w0, &w2, &w1, x[16], y[21]); - word3_muladd(&w0, &w2, &w1, x[17], y[20]); - word3_muladd(&w0, &w2, &w1, x[18], y[19]); - word3_muladd(&w0, &w2, &w1, x[19], y[18]); - word3_muladd(&w0, &w2, &w1, x[20], y[17]); - word3_muladd(&w0, &w2, &w1, x[21], y[16]); - word3_muladd(&w0, &w2, &w1, x[22], y[15]); - word3_muladd(&w0, &w2, &w1, x[23], y[14]); - z[37] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[15], y[23]); - word3_muladd(&w1, &w0, &w2, x[16], y[22]); - word3_muladd(&w1, &w0, &w2, x[17], y[21]); - word3_muladd(&w1, &w0, &w2, x[18], y[20]); - word3_muladd(&w1, &w0, &w2, x[19], y[19]); - word3_muladd(&w1, &w0, &w2, x[20], y[18]); - word3_muladd(&w1, &w0, &w2, x[21], y[17]); - word3_muladd(&w1, &w0, &w2, x[22], y[16]); - word3_muladd(&w1, &w0, &w2, x[23], y[15]); - z[38] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[16], y[23]); - word3_muladd(&w2, &w1, &w0, x[17], y[22]); - word3_muladd(&w2, &w1, &w0, x[18], y[21]); - word3_muladd(&w2, &w1, &w0, x[19], y[20]); - word3_muladd(&w2, &w1, &w0, x[20], y[19]); - word3_muladd(&w2, &w1, &w0, x[21], y[18]); - word3_muladd(&w2, &w1, &w0, x[22], y[17]); - word3_muladd(&w2, &w1, &w0, x[23], y[16]); - z[39] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[17], y[23]); - word3_muladd(&w0, &w2, &w1, x[18], y[22]); - word3_muladd(&w0, &w2, &w1, x[19], y[21]); - word3_muladd(&w0, &w2, &w1, x[20], y[20]); - word3_muladd(&w0, &w2, &w1, x[21], y[19]); - word3_muladd(&w0, &w2, &w1, x[22], y[18]); - word3_muladd(&w0, &w2, &w1, x[23], y[17]); - z[40] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[18], y[23]); - word3_muladd(&w1, &w0, &w2, x[19], y[22]); - word3_muladd(&w1, &w0, &w2, x[20], y[21]); - word3_muladd(&w1, &w0, &w2, x[21], y[20]); - word3_muladd(&w1, &w0, &w2, x[22], y[19]); - word3_muladd(&w1, &w0, &w2, x[23], y[18]); - z[41] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[19], y[23]); - word3_muladd(&w2, &w1, &w0, x[20], y[22]); - word3_muladd(&w2, &w1, &w0, x[21], y[21]); - word3_muladd(&w2, &w1, &w0, x[22], y[20]); - word3_muladd(&w2, &w1, &w0, x[23], y[19]); - z[42] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[20], y[23]); - word3_muladd(&w0, &w2, &w1, x[21], y[22]); - word3_muladd(&w0, &w2, &w1, x[22], y[21]); - word3_muladd(&w0, &w2, &w1, x[23], y[20]); - z[43] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[21], y[23]); - word3_muladd(&w1, &w0, &w2, x[22], y[22]); - word3_muladd(&w1, &w0, &w2, x[23], y[21]); - z[44] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[22], y[23]); - word3_muladd(&w2, &w1, &w0, x[23], y[22]); - z[45] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[23], y[23]); - z[46] = w1; - z[47] = w2; - } - + * Comba 4x4 Squaring + */ +void bigint_comba_sqr4(word z[8], const word x[4]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], x[0]); + z[0] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[1]); + z[1] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[2]); + word3_muladd(&w1, &w0, &w2, x[1], x[1]); + z[2] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); + z[3] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[1], x[3]); + word3_muladd(&w0, &w2, &w1, x[2], x[2]); + z[4] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[2], x[3]); + z[5] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[3], x[3]); + z[6] = w0; + z[7] = w1; } -/* -* Multiplication and Squaring -* (C) 1999-2010,2018 Jack Lloyd -* 2016 Matthias Gierlings -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Comba 4x4 Multiplication + */ +void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[0]); + z[0] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[1]); + word3_muladd(&w0, &w2, &w1, x[1], y[0]); + z[1] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[2]); + word3_muladd(&w1, &w0, &w2, x[1], y[1]); + word3_muladd(&w1, &w0, &w2, x[2], y[0]); + z[2] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[3]); + word3_muladd(&w2, &w1, &w0, x[1], y[2]); + word3_muladd(&w2, &w1, &w0, x[2], y[1]); + word3_muladd(&w2, &w1, &w0, x[3], y[0]); + z[3] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[1], y[3]); + word3_muladd(&w0, &w2, &w1, x[2], y[2]); + word3_muladd(&w0, &w2, &w1, x[3], y[1]); + z[4] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[2], y[3]); + word3_muladd(&w1, &w0, &w2, x[3], y[2]); + z[5] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[3], y[3]); + z[6] = w0; + z[7] = w1; +} + +/* + * Comba 6x6 Squaring + */ +void bigint_comba_sqr6(word z[12], const word x[6]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], x[0]); + z[0] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[1]); + z[1] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[2]); + word3_muladd(&w1, &w0, &w2, x[1], x[1]); + z[2] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); + z[3] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[4]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[3]); + word3_muladd(&w0, &w2, &w1, x[2], x[2]); + z[4] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[5]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[4]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[3]); + z[5] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[1], x[5]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[4]); + word3_muladd(&w2, &w1, &w0, x[3], x[3]); + z[6] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[2], x[5]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[4]); + z[7] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[3], x[5]); + word3_muladd(&w1, &w0, &w2, x[4], x[4]); + z[8] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[4], x[5]); + z[9] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[5], x[5]); + z[10] = w1; + z[11] = w2; +} + +/* + * Comba 6x6 Multiplication + */ +void bigint_comba_mul6(word z[12], const word x[6], const word y[6]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[0]); + z[0] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[1]); + word3_muladd(&w0, &w2, &w1, x[1], y[0]); + z[1] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[2]); + word3_muladd(&w1, &w0, &w2, x[1], y[1]); + word3_muladd(&w1, &w0, &w2, x[2], y[0]); + z[2] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[3]); + word3_muladd(&w2, &w1, &w0, x[1], y[2]); + word3_muladd(&w2, &w1, &w0, x[2], y[1]); + word3_muladd(&w2, &w1, &w0, x[3], y[0]); + z[3] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[4]); + word3_muladd(&w0, &w2, &w1, x[1], y[3]); + word3_muladd(&w0, &w2, &w1, x[2], y[2]); + word3_muladd(&w0, &w2, &w1, x[3], y[1]); + word3_muladd(&w0, &w2, &w1, x[4], y[0]); + z[4] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[5]); + word3_muladd(&w1, &w0, &w2, x[1], y[4]); + word3_muladd(&w1, &w0, &w2, x[2], y[3]); + word3_muladd(&w1, &w0, &w2, x[3], y[2]); + word3_muladd(&w1, &w0, &w2, x[4], y[1]); + word3_muladd(&w1, &w0, &w2, x[5], y[0]); + z[5] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[1], y[5]); + word3_muladd(&w2, &w1, &w0, x[2], y[4]); + word3_muladd(&w2, &w1, &w0, x[3], y[3]); + word3_muladd(&w2, &w1, &w0, x[4], y[2]); + word3_muladd(&w2, &w1, &w0, x[5], y[1]); + z[6] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[2], y[5]); + word3_muladd(&w0, &w2, &w1, x[3], y[4]); + word3_muladd(&w0, &w2, &w1, x[4], y[3]); + word3_muladd(&w0, &w2, &w1, x[5], y[2]); + z[7] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[3], y[5]); + word3_muladd(&w1, &w0, &w2, x[4], y[4]); + word3_muladd(&w1, &w0, &w2, x[5], y[3]); + z[8] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[4], y[5]); + word3_muladd(&w2, &w1, &w0, x[5], y[4]); + z[9] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[5], y[5]); + z[10] = w1; + z[11] = w2; +} + +/* + * Comba 8x8 Squaring + */ +void bigint_comba_sqr8(word z[16], const word x[8]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], x[0]); + z[0] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[1]); + z[1] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[2]); + word3_muladd(&w1, &w0, &w2, x[1], x[1]); + z[2] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); + z[3] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[4]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[3]); + word3_muladd(&w0, &w2, &w1, x[2], x[2]); + z[4] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[5]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[4]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[3]); + z[5] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[6]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[5]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[4]); + word3_muladd(&w2, &w1, &w0, x[3], x[3]); + z[6] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[7]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[6]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[5]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[4]); + z[7] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[1], x[7]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[6]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[5]); + word3_muladd(&w1, &w0, &w2, x[4], x[4]); + z[8] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[2], x[7]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[6]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[5]); + z[9] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[3], x[7]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[6]); + word3_muladd(&w0, &w2, &w1, x[5], x[5]); + z[10] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[4], x[7]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[6]); + z[11] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[5], x[7]); + word3_muladd(&w2, &w1, &w0, x[6], x[6]); + z[12] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[6], x[7]); + z[13] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[7], x[7]); + z[14] = w2; + z[15] = w0; +} + +/* + * Comba 8x8 Multiplication + */ +void bigint_comba_mul8(word z[16], const word x[8], const word y[8]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[0]); + z[0] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[1]); + word3_muladd(&w0, &w2, &w1, x[1], y[0]); + z[1] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[2]); + word3_muladd(&w1, &w0, &w2, x[1], y[1]); + word3_muladd(&w1, &w0, &w2, x[2], y[0]); + z[2] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[3]); + word3_muladd(&w2, &w1, &w0, x[1], y[2]); + word3_muladd(&w2, &w1, &w0, x[2], y[1]); + word3_muladd(&w2, &w1, &w0, x[3], y[0]); + z[3] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[4]); + word3_muladd(&w0, &w2, &w1, x[1], y[3]); + word3_muladd(&w0, &w2, &w1, x[2], y[2]); + word3_muladd(&w0, &w2, &w1, x[3], y[1]); + word3_muladd(&w0, &w2, &w1, x[4], y[0]); + z[4] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[5]); + word3_muladd(&w1, &w0, &w2, x[1], y[4]); + word3_muladd(&w1, &w0, &w2, x[2], y[3]); + word3_muladd(&w1, &w0, &w2, x[3], y[2]); + word3_muladd(&w1, &w0, &w2, x[4], y[1]); + word3_muladd(&w1, &w0, &w2, x[5], y[0]); + z[5] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[6]); + word3_muladd(&w2, &w1, &w0, x[1], y[5]); + word3_muladd(&w2, &w1, &w0, x[2], y[4]); + word3_muladd(&w2, &w1, &w0, x[3], y[3]); + word3_muladd(&w2, &w1, &w0, x[4], y[2]); + word3_muladd(&w2, &w1, &w0, x[5], y[1]); + word3_muladd(&w2, &w1, &w0, x[6], y[0]); + z[6] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[7]); + word3_muladd(&w0, &w2, &w1, x[1], y[6]); + word3_muladd(&w0, &w2, &w1, x[2], y[5]); + word3_muladd(&w0, &w2, &w1, x[3], y[4]); + word3_muladd(&w0, &w2, &w1, x[4], y[3]); + word3_muladd(&w0, &w2, &w1, x[5], y[2]); + word3_muladd(&w0, &w2, &w1, x[6], y[1]); + word3_muladd(&w0, &w2, &w1, x[7], y[0]); + z[7] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[1], y[7]); + word3_muladd(&w1, &w0, &w2, x[2], y[6]); + word3_muladd(&w1, &w0, &w2, x[3], y[5]); + word3_muladd(&w1, &w0, &w2, x[4], y[4]); + word3_muladd(&w1, &w0, &w2, x[5], y[3]); + word3_muladd(&w1, &w0, &w2, x[6], y[2]); + word3_muladd(&w1, &w0, &w2, x[7], y[1]); + z[8] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[2], y[7]); + word3_muladd(&w2, &w1, &w0, x[3], y[6]); + word3_muladd(&w2, &w1, &w0, x[4], y[5]); + word3_muladd(&w2, &w1, &w0, x[5], y[4]); + word3_muladd(&w2, &w1, &w0, x[6], y[3]); + word3_muladd(&w2, &w1, &w0, x[7], y[2]); + z[9] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[3], y[7]); + word3_muladd(&w0, &w2, &w1, x[4], y[6]); + word3_muladd(&w0, &w2, &w1, x[5], y[5]); + word3_muladd(&w0, &w2, &w1, x[6], y[4]); + word3_muladd(&w0, &w2, &w1, x[7], y[3]); + z[10] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[4], y[7]); + word3_muladd(&w1, &w0, &w2, x[5], y[6]); + word3_muladd(&w1, &w0, &w2, x[6], y[5]); + word3_muladd(&w1, &w0, &w2, x[7], y[4]); + z[11] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[5], y[7]); + word3_muladd(&w2, &w1, &w0, x[6], y[6]); + word3_muladd(&w2, &w1, &w0, x[7], y[5]); + z[12] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[6], y[7]); + word3_muladd(&w0, &w2, &w1, x[7], y[6]); + z[13] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[7], y[7]); + z[14] = w2; + z[15] = w0; +} + +/* + * Comba 9x9 Squaring + */ +void bigint_comba_sqr9(word z[18], const word x[9]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], x[0]); + z[0] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[1]); + z[1] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[2]); + word3_muladd(&w1, &w0, &w2, x[1], x[1]); + z[2] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); + z[3] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[4]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[3]); + word3_muladd(&w0, &w2, &w1, x[2], x[2]); + z[4] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[5]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[4]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[3]); + z[5] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[6]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[5]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[4]); + word3_muladd(&w2, &w1, &w0, x[3], x[3]); + z[6] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[7]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[6]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[5]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[4]); + z[7] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[8]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[7]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[6]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[5]); + word3_muladd(&w1, &w0, &w2, x[4], x[4]); + z[8] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[1], x[8]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[7]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[6]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[5]); + z[9] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[2], x[8]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[7]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[6]); + word3_muladd(&w0, &w2, &w1, x[5], x[5]); + z[10] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[3], x[8]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[7]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[6]); + z[11] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[4], x[8]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[7]); + word3_muladd(&w2, &w1, &w0, x[6], x[6]); + z[12] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[5], x[8]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[7]); + z[13] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[6], x[8]); + word3_muladd(&w1, &w0, &w2, x[7], x[7]); + z[14] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[7], x[8]); + z[15] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[8], x[8]); + z[16] = w1; + z[17] = w2; +} + +/* + * Comba 9x9 Multiplication + */ +void bigint_comba_mul9(word z[18], const word x[9], const word y[9]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[0]); + z[0] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[1]); + word3_muladd(&w0, &w2, &w1, x[1], y[0]); + z[1] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[2]); + word3_muladd(&w1, &w0, &w2, x[1], y[1]); + word3_muladd(&w1, &w0, &w2, x[2], y[0]); + z[2] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[3]); + word3_muladd(&w2, &w1, &w0, x[1], y[2]); + word3_muladd(&w2, &w1, &w0, x[2], y[1]); + word3_muladd(&w2, &w1, &w0, x[3], y[0]); + z[3] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[4]); + word3_muladd(&w0, &w2, &w1, x[1], y[3]); + word3_muladd(&w0, &w2, &w1, x[2], y[2]); + word3_muladd(&w0, &w2, &w1, x[3], y[1]); + word3_muladd(&w0, &w2, &w1, x[4], y[0]); + z[4] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[5]); + word3_muladd(&w1, &w0, &w2, x[1], y[4]); + word3_muladd(&w1, &w0, &w2, x[2], y[3]); + word3_muladd(&w1, &w0, &w2, x[3], y[2]); + word3_muladd(&w1, &w0, &w2, x[4], y[1]); + word3_muladd(&w1, &w0, &w2, x[5], y[0]); + z[5] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[6]); + word3_muladd(&w2, &w1, &w0, x[1], y[5]); + word3_muladd(&w2, &w1, &w0, x[2], y[4]); + word3_muladd(&w2, &w1, &w0, x[3], y[3]); + word3_muladd(&w2, &w1, &w0, x[4], y[2]); + word3_muladd(&w2, &w1, &w0, x[5], y[1]); + word3_muladd(&w2, &w1, &w0, x[6], y[0]); + z[6] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[7]); + word3_muladd(&w0, &w2, &w1, x[1], y[6]); + word3_muladd(&w0, &w2, &w1, x[2], y[5]); + word3_muladd(&w0, &w2, &w1, x[3], y[4]); + word3_muladd(&w0, &w2, &w1, x[4], y[3]); + word3_muladd(&w0, &w2, &w1, x[5], y[2]); + word3_muladd(&w0, &w2, &w1, x[6], y[1]); + word3_muladd(&w0, &w2, &w1, x[7], y[0]); + z[7] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[8]); + word3_muladd(&w1, &w0, &w2, x[1], y[7]); + word3_muladd(&w1, &w0, &w2, x[2], y[6]); + word3_muladd(&w1, &w0, &w2, x[3], y[5]); + word3_muladd(&w1, &w0, &w2, x[4], y[4]); + word3_muladd(&w1, &w0, &w2, x[5], y[3]); + word3_muladd(&w1, &w0, &w2, x[6], y[2]); + word3_muladd(&w1, &w0, &w2, x[7], y[1]); + word3_muladd(&w1, &w0, &w2, x[8], y[0]); + z[8] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[1], y[8]); + word3_muladd(&w2, &w1, &w0, x[2], y[7]); + word3_muladd(&w2, &w1, &w0, x[3], y[6]); + word3_muladd(&w2, &w1, &w0, x[4], y[5]); + word3_muladd(&w2, &w1, &w0, x[5], y[4]); + word3_muladd(&w2, &w1, &w0, x[6], y[3]); + word3_muladd(&w2, &w1, &w0, x[7], y[2]); + word3_muladd(&w2, &w1, &w0, x[8], y[1]); + z[9] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[2], y[8]); + word3_muladd(&w0, &w2, &w1, x[3], y[7]); + word3_muladd(&w0, &w2, &w1, x[4], y[6]); + word3_muladd(&w0, &w2, &w1, x[5], y[5]); + word3_muladd(&w0, &w2, &w1, x[6], y[4]); + word3_muladd(&w0, &w2, &w1, x[7], y[3]); + word3_muladd(&w0, &w2, &w1, x[8], y[2]); + z[10] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[3], y[8]); + word3_muladd(&w1, &w0, &w2, x[4], y[7]); + word3_muladd(&w1, &w0, &w2, x[5], y[6]); + word3_muladd(&w1, &w0, &w2, x[6], y[5]); + word3_muladd(&w1, &w0, &w2, x[7], y[4]); + word3_muladd(&w1, &w0, &w2, x[8], y[3]); + z[11] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[4], y[8]); + word3_muladd(&w2, &w1, &w0, x[5], y[7]); + word3_muladd(&w2, &w1, &w0, x[6], y[6]); + word3_muladd(&w2, &w1, &w0, x[7], y[5]); + word3_muladd(&w2, &w1, &w0, x[8], y[4]); + z[12] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[5], y[8]); + word3_muladd(&w0, &w2, &w1, x[6], y[7]); + word3_muladd(&w0, &w2, &w1, x[7], y[6]); + word3_muladd(&w0, &w2, &w1, x[8], y[5]); + z[13] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[6], y[8]); + word3_muladd(&w1, &w0, &w2, x[7], y[7]); + word3_muladd(&w1, &w0, &w2, x[8], y[6]); + z[14] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[7], y[8]); + word3_muladd(&w2, &w1, &w0, x[8], y[7]); + z[15] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[8], y[8]); + z[16] = w1; + z[17] = w2; +} + +/* + * Comba 16x16 Squaring + */ +void bigint_comba_sqr16(word z[32], const word x[16]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], x[0]); + z[0] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[1]); + z[1] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[2]); + word3_muladd(&w1, &w0, &w2, x[1], x[1]); + z[2] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); + z[3] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[4]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[3]); + word3_muladd(&w0, &w2, &w1, x[2], x[2]); + z[4] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[5]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[4]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[3]); + z[5] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[6]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[5]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[4]); + word3_muladd(&w2, &w1, &w0, x[3], x[3]); + z[6] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[7]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[6]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[5]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[4]); + z[7] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[8]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[7]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[6]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[5]); + word3_muladd(&w1, &w0, &w2, x[4], x[4]); + z[8] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[9]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[8]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[7]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[6]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[5]); + z[9] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[9]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[8]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[7]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[6]); + word3_muladd(&w0, &w2, &w1, x[5], x[5]); + z[10] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[9]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[8]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[7]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[6]); + z[11] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[10]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[9]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[8]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[7]); + word3_muladd(&w2, &w1, &w0, x[6], x[6]); + z[12] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[9]); + word3_muladd_2(&w0, &w2, &w1, x[5], x[8]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[7]); + z[13] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[9]); + word3_muladd_2(&w1, &w0, &w2, x[6], x[8]); + word3_muladd(&w1, &w0, &w2, x[7], x[7]); + z[14] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[10]); + word3_muladd_2(&w2, &w1, &w0, x[6], x[9]); + word3_muladd_2(&w2, &w1, &w0, x[7], x[8]); + z[15] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[1], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[5], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[7], x[9]); + word3_muladd(&w0, &w2, &w1, x[8], x[8]); + z[16] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[2], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[6], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[7], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[8], x[9]); + z[17] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[3], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[6], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[7], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[8], x[10]); + word3_muladd(&w2, &w1, &w0, x[9], x[9]); + z[18] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[4], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[5], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[7], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[8], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[9], x[10]); + z[19] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[5], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[6], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[7], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[8], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[9], x[11]); + word3_muladd(&w1, &w0, &w2, x[10], x[10]); + z[20] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[6], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[7], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[8], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[9], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[11]); + z[21] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[7], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[8], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[9], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[12]); + word3_muladd(&w0, &w2, &w1, x[11], x[11]); + z[22] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[8], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[9], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[12]); + z[23] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[9], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[13]); + word3_muladd(&w2, &w1, &w0, x[12], x[12]); + z[24] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[10], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[13]); + z[25] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[11], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[14]); + word3_muladd(&w1, &w0, &w2, x[13], x[13]); + z[26] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[12], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[13], x[14]); + z[27] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[13], x[15]); + word3_muladd(&w0, &w2, &w1, x[14], x[14]); + z[28] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[14], x[15]); + z[29] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[15], x[15]); + z[30] = w0; + z[31] = w1; +} + +/* + * Comba 16x16 Multiplication + */ +void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[0]); + z[0] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[1]); + word3_muladd(&w0, &w2, &w1, x[1], y[0]); + z[1] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[2]); + word3_muladd(&w1, &w0, &w2, x[1], y[1]); + word3_muladd(&w1, &w0, &w2, x[2], y[0]); + z[2] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[3]); + word3_muladd(&w2, &w1, &w0, x[1], y[2]); + word3_muladd(&w2, &w1, &w0, x[2], y[1]); + word3_muladd(&w2, &w1, &w0, x[3], y[0]); + z[3] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[4]); + word3_muladd(&w0, &w2, &w1, x[1], y[3]); + word3_muladd(&w0, &w2, &w1, x[2], y[2]); + word3_muladd(&w0, &w2, &w1, x[3], y[1]); + word3_muladd(&w0, &w2, &w1, x[4], y[0]); + z[4] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[5]); + word3_muladd(&w1, &w0, &w2, x[1], y[4]); + word3_muladd(&w1, &w0, &w2, x[2], y[3]); + word3_muladd(&w1, &w0, &w2, x[3], y[2]); + word3_muladd(&w1, &w0, &w2, x[4], y[1]); + word3_muladd(&w1, &w0, &w2, x[5], y[0]); + z[5] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[6]); + word3_muladd(&w2, &w1, &w0, x[1], y[5]); + word3_muladd(&w2, &w1, &w0, x[2], y[4]); + word3_muladd(&w2, &w1, &w0, x[3], y[3]); + word3_muladd(&w2, &w1, &w0, x[4], y[2]); + word3_muladd(&w2, &w1, &w0, x[5], y[1]); + word3_muladd(&w2, &w1, &w0, x[6], y[0]); + z[6] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[7]); + word3_muladd(&w0, &w2, &w1, x[1], y[6]); + word3_muladd(&w0, &w2, &w1, x[2], y[5]); + word3_muladd(&w0, &w2, &w1, x[3], y[4]); + word3_muladd(&w0, &w2, &w1, x[4], y[3]); + word3_muladd(&w0, &w2, &w1, x[5], y[2]); + word3_muladd(&w0, &w2, &w1, x[6], y[1]); + word3_muladd(&w0, &w2, &w1, x[7], y[0]); + z[7] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[8]); + word3_muladd(&w1, &w0, &w2, x[1], y[7]); + word3_muladd(&w1, &w0, &w2, x[2], y[6]); + word3_muladd(&w1, &w0, &w2, x[3], y[5]); + word3_muladd(&w1, &w0, &w2, x[4], y[4]); + word3_muladd(&w1, &w0, &w2, x[5], y[3]); + word3_muladd(&w1, &w0, &w2, x[6], y[2]); + word3_muladd(&w1, &w0, &w2, x[7], y[1]); + word3_muladd(&w1, &w0, &w2, x[8], y[0]); + z[8] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[9]); + word3_muladd(&w2, &w1, &w0, x[1], y[8]); + word3_muladd(&w2, &w1, &w0, x[2], y[7]); + word3_muladd(&w2, &w1, &w0, x[3], y[6]); + word3_muladd(&w2, &w1, &w0, x[4], y[5]); + word3_muladd(&w2, &w1, &w0, x[5], y[4]); + word3_muladd(&w2, &w1, &w0, x[6], y[3]); + word3_muladd(&w2, &w1, &w0, x[7], y[2]); + word3_muladd(&w2, &w1, &w0, x[8], y[1]); + word3_muladd(&w2, &w1, &w0, x[9], y[0]); + z[9] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[10]); + word3_muladd(&w0, &w2, &w1, x[1], y[9]); + word3_muladd(&w0, &w2, &w1, x[2], y[8]); + word3_muladd(&w0, &w2, &w1, x[3], y[7]); + word3_muladd(&w0, &w2, &w1, x[4], y[6]); + word3_muladd(&w0, &w2, &w1, x[5], y[5]); + word3_muladd(&w0, &w2, &w1, x[6], y[4]); + word3_muladd(&w0, &w2, &w1, x[7], y[3]); + word3_muladd(&w0, &w2, &w1, x[8], y[2]); + word3_muladd(&w0, &w2, &w1, x[9], y[1]); + word3_muladd(&w0, &w2, &w1, x[10], y[0]); + z[10] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[11]); + word3_muladd(&w1, &w0, &w2, x[1], y[10]); + word3_muladd(&w1, &w0, &w2, x[2], y[9]); + word3_muladd(&w1, &w0, &w2, x[3], y[8]); + word3_muladd(&w1, &w0, &w2, x[4], y[7]); + word3_muladd(&w1, &w0, &w2, x[5], y[6]); + word3_muladd(&w1, &w0, &w2, x[6], y[5]); + word3_muladd(&w1, &w0, &w2, x[7], y[4]); + word3_muladd(&w1, &w0, &w2, x[8], y[3]); + word3_muladd(&w1, &w0, &w2, x[9], y[2]); + word3_muladd(&w1, &w0, &w2, x[10], y[1]); + word3_muladd(&w1, &w0, &w2, x[11], y[0]); + z[11] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[12]); + word3_muladd(&w2, &w1, &w0, x[1], y[11]); + word3_muladd(&w2, &w1, &w0, x[2], y[10]); + word3_muladd(&w2, &w1, &w0, x[3], y[9]); + word3_muladd(&w2, &w1, &w0, x[4], y[8]); + word3_muladd(&w2, &w1, &w0, x[5], y[7]); + word3_muladd(&w2, &w1, &w0, x[6], y[6]); + word3_muladd(&w2, &w1, &w0, x[7], y[5]); + word3_muladd(&w2, &w1, &w0, x[8], y[4]); + word3_muladd(&w2, &w1, &w0, x[9], y[3]); + word3_muladd(&w2, &w1, &w0, x[10], y[2]); + word3_muladd(&w2, &w1, &w0, x[11], y[1]); + word3_muladd(&w2, &w1, &w0, x[12], y[0]); + z[12] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[13]); + word3_muladd(&w0, &w2, &w1, x[1], y[12]); + word3_muladd(&w0, &w2, &w1, x[2], y[11]); + word3_muladd(&w0, &w2, &w1, x[3], y[10]); + word3_muladd(&w0, &w2, &w1, x[4], y[9]); + word3_muladd(&w0, &w2, &w1, x[5], y[8]); + word3_muladd(&w0, &w2, &w1, x[6], y[7]); + word3_muladd(&w0, &w2, &w1, x[7], y[6]); + word3_muladd(&w0, &w2, &w1, x[8], y[5]); + word3_muladd(&w0, &w2, &w1, x[9], y[4]); + word3_muladd(&w0, &w2, &w1, x[10], y[3]); + word3_muladd(&w0, &w2, &w1, x[11], y[2]); + word3_muladd(&w0, &w2, &w1, x[12], y[1]); + word3_muladd(&w0, &w2, &w1, x[13], y[0]); + z[13] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[14]); + word3_muladd(&w1, &w0, &w2, x[1], y[13]); + word3_muladd(&w1, &w0, &w2, x[2], y[12]); + word3_muladd(&w1, &w0, &w2, x[3], y[11]); + word3_muladd(&w1, &w0, &w2, x[4], y[10]); + word3_muladd(&w1, &w0, &w2, x[5], y[9]); + word3_muladd(&w1, &w0, &w2, x[6], y[8]); + word3_muladd(&w1, &w0, &w2, x[7], y[7]); + word3_muladd(&w1, &w0, &w2, x[8], y[6]); + word3_muladd(&w1, &w0, &w2, x[9], y[5]); + word3_muladd(&w1, &w0, &w2, x[10], y[4]); + word3_muladd(&w1, &w0, &w2, x[11], y[3]); + word3_muladd(&w1, &w0, &w2, x[12], y[2]); + word3_muladd(&w1, &w0, &w2, x[13], y[1]); + word3_muladd(&w1, &w0, &w2, x[14], y[0]); + z[14] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[15]); + word3_muladd(&w2, &w1, &w0, x[1], y[14]); + word3_muladd(&w2, &w1, &w0, x[2], y[13]); + word3_muladd(&w2, &w1, &w0, x[3], y[12]); + word3_muladd(&w2, &w1, &w0, x[4], y[11]); + word3_muladd(&w2, &w1, &w0, x[5], y[10]); + word3_muladd(&w2, &w1, &w0, x[6], y[9]); + word3_muladd(&w2, &w1, &w0, x[7], y[8]); + word3_muladd(&w2, &w1, &w0, x[8], y[7]); + word3_muladd(&w2, &w1, &w0, x[9], y[6]); + word3_muladd(&w2, &w1, &w0, x[10], y[5]); + word3_muladd(&w2, &w1, &w0, x[11], y[4]); + word3_muladd(&w2, &w1, &w0, x[12], y[3]); + word3_muladd(&w2, &w1, &w0, x[13], y[2]); + word3_muladd(&w2, &w1, &w0, x[14], y[1]); + word3_muladd(&w2, &w1, &w0, x[15], y[0]); + z[15] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[1], y[15]); + word3_muladd(&w0, &w2, &w1, x[2], y[14]); + word3_muladd(&w0, &w2, &w1, x[3], y[13]); + word3_muladd(&w0, &w2, &w1, x[4], y[12]); + word3_muladd(&w0, &w2, &w1, x[5], y[11]); + word3_muladd(&w0, &w2, &w1, x[6], y[10]); + word3_muladd(&w0, &w2, &w1, x[7], y[9]); + word3_muladd(&w0, &w2, &w1, x[8], y[8]); + word3_muladd(&w0, &w2, &w1, x[9], y[7]); + word3_muladd(&w0, &w2, &w1, x[10], y[6]); + word3_muladd(&w0, &w2, &w1, x[11], y[5]); + word3_muladd(&w0, &w2, &w1, x[12], y[4]); + word3_muladd(&w0, &w2, &w1, x[13], y[3]); + word3_muladd(&w0, &w2, &w1, x[14], y[2]); + word3_muladd(&w0, &w2, &w1, x[15], y[1]); + z[16] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[2], y[15]); + word3_muladd(&w1, &w0, &w2, x[3], y[14]); + word3_muladd(&w1, &w0, &w2, x[4], y[13]); + word3_muladd(&w1, &w0, &w2, x[5], y[12]); + word3_muladd(&w1, &w0, &w2, x[6], y[11]); + word3_muladd(&w1, &w0, &w2, x[7], y[10]); + word3_muladd(&w1, &w0, &w2, x[8], y[9]); + word3_muladd(&w1, &w0, &w2, x[9], y[8]); + word3_muladd(&w1, &w0, &w2, x[10], y[7]); + word3_muladd(&w1, &w0, &w2, x[11], y[6]); + word3_muladd(&w1, &w0, &w2, x[12], y[5]); + word3_muladd(&w1, &w0, &w2, x[13], y[4]); + word3_muladd(&w1, &w0, &w2, x[14], y[3]); + word3_muladd(&w1, &w0, &w2, x[15], y[2]); + z[17] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[3], y[15]); + word3_muladd(&w2, &w1, &w0, x[4], y[14]); + word3_muladd(&w2, &w1, &w0, x[5], y[13]); + word3_muladd(&w2, &w1, &w0, x[6], y[12]); + word3_muladd(&w2, &w1, &w0, x[7], y[11]); + word3_muladd(&w2, &w1, &w0, x[8], y[10]); + word3_muladd(&w2, &w1, &w0, x[9], y[9]); + word3_muladd(&w2, &w1, &w0, x[10], y[8]); + word3_muladd(&w2, &w1, &w0, x[11], y[7]); + word3_muladd(&w2, &w1, &w0, x[12], y[6]); + word3_muladd(&w2, &w1, &w0, x[13], y[5]); + word3_muladd(&w2, &w1, &w0, x[14], y[4]); + word3_muladd(&w2, &w1, &w0, x[15], y[3]); + z[18] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[4], y[15]); + word3_muladd(&w0, &w2, &w1, x[5], y[14]); + word3_muladd(&w0, &w2, &w1, x[6], y[13]); + word3_muladd(&w0, &w2, &w1, x[7], y[12]); + word3_muladd(&w0, &w2, &w1, x[8], y[11]); + word3_muladd(&w0, &w2, &w1, x[9], y[10]); + word3_muladd(&w0, &w2, &w1, x[10], y[9]); + word3_muladd(&w0, &w2, &w1, x[11], y[8]); + word3_muladd(&w0, &w2, &w1, x[12], y[7]); + word3_muladd(&w0, &w2, &w1, x[13], y[6]); + word3_muladd(&w0, &w2, &w1, x[14], y[5]); + word3_muladd(&w0, &w2, &w1, x[15], y[4]); + z[19] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[5], y[15]); + word3_muladd(&w1, &w0, &w2, x[6], y[14]); + word3_muladd(&w1, &w0, &w2, x[7], y[13]); + word3_muladd(&w1, &w0, &w2, x[8], y[12]); + word3_muladd(&w1, &w0, &w2, x[9], y[11]); + word3_muladd(&w1, &w0, &w2, x[10], y[10]); + word3_muladd(&w1, &w0, &w2, x[11], y[9]); + word3_muladd(&w1, &w0, &w2, x[12], y[8]); + word3_muladd(&w1, &w0, &w2, x[13], y[7]); + word3_muladd(&w1, &w0, &w2, x[14], y[6]); + word3_muladd(&w1, &w0, &w2, x[15], y[5]); + z[20] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[6], y[15]); + word3_muladd(&w2, &w1, &w0, x[7], y[14]); + word3_muladd(&w2, &w1, &w0, x[8], y[13]); + word3_muladd(&w2, &w1, &w0, x[9], y[12]); + word3_muladd(&w2, &w1, &w0, x[10], y[11]); + word3_muladd(&w2, &w1, &w0, x[11], y[10]); + word3_muladd(&w2, &w1, &w0, x[12], y[9]); + word3_muladd(&w2, &w1, &w0, x[13], y[8]); + word3_muladd(&w2, &w1, &w0, x[14], y[7]); + word3_muladd(&w2, &w1, &w0, x[15], y[6]); + z[21] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[7], y[15]); + word3_muladd(&w0, &w2, &w1, x[8], y[14]); + word3_muladd(&w0, &w2, &w1, x[9], y[13]); + word3_muladd(&w0, &w2, &w1, x[10], y[12]); + word3_muladd(&w0, &w2, &w1, x[11], y[11]); + word3_muladd(&w0, &w2, &w1, x[12], y[10]); + word3_muladd(&w0, &w2, &w1, x[13], y[9]); + word3_muladd(&w0, &w2, &w1, x[14], y[8]); + word3_muladd(&w0, &w2, &w1, x[15], y[7]); + z[22] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[8], y[15]); + word3_muladd(&w1, &w0, &w2, x[9], y[14]); + word3_muladd(&w1, &w0, &w2, x[10], y[13]); + word3_muladd(&w1, &w0, &w2, x[11], y[12]); + word3_muladd(&w1, &w0, &w2, x[12], y[11]); + word3_muladd(&w1, &w0, &w2, x[13], y[10]); + word3_muladd(&w1, &w0, &w2, x[14], y[9]); + word3_muladd(&w1, &w0, &w2, x[15], y[8]); + z[23] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[9], y[15]); + word3_muladd(&w2, &w1, &w0, x[10], y[14]); + word3_muladd(&w2, &w1, &w0, x[11], y[13]); + word3_muladd(&w2, &w1, &w0, x[12], y[12]); + word3_muladd(&w2, &w1, &w0, x[13], y[11]); + word3_muladd(&w2, &w1, &w0, x[14], y[10]); + word3_muladd(&w2, &w1, &w0, x[15], y[9]); + z[24] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[10], y[15]); + word3_muladd(&w0, &w2, &w1, x[11], y[14]); + word3_muladd(&w0, &w2, &w1, x[12], y[13]); + word3_muladd(&w0, &w2, &w1, x[13], y[12]); + word3_muladd(&w0, &w2, &w1, x[14], y[11]); + word3_muladd(&w0, &w2, &w1, x[15], y[10]); + z[25] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[11], y[15]); + word3_muladd(&w1, &w0, &w2, x[12], y[14]); + word3_muladd(&w1, &w0, &w2, x[13], y[13]); + word3_muladd(&w1, &w0, &w2, x[14], y[12]); + word3_muladd(&w1, &w0, &w2, x[15], y[11]); + z[26] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[12], y[15]); + word3_muladd(&w2, &w1, &w0, x[13], y[14]); + word3_muladd(&w2, &w1, &w0, x[14], y[13]); + word3_muladd(&w2, &w1, &w0, x[15], y[12]); + z[27] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[13], y[15]); + word3_muladd(&w0, &w2, &w1, x[14], y[14]); + word3_muladd(&w0, &w2, &w1, x[15], y[13]); + z[28] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[14], y[15]); + word3_muladd(&w1, &w0, &w2, x[15], y[14]); + z[29] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[15], y[15]); + z[30] = w0; + z[31] = w1; +} + +/* + * Comba 24x24 Squaring + */ +void bigint_comba_sqr24(word z[48], const word x[24]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], x[0]); + z[0] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[1]); + z[1] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[2]); + word3_muladd(&w1, &w0, &w2, x[1], x[1]); + z[2] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); + z[3] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[4]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[3]); + word3_muladd(&w0, &w2, &w1, x[2], x[2]); + z[4] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[5]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[4]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[3]); + z[5] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[6]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[5]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[4]); + word3_muladd(&w2, &w1, &w0, x[3], x[3]); + z[6] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[7]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[6]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[5]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[4]); + z[7] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[8]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[7]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[6]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[5]); + word3_muladd(&w1, &w0, &w2, x[4], x[4]); + z[8] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[9]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[8]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[7]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[6]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[5]); + z[9] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[9]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[8]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[7]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[6]); + word3_muladd(&w0, &w2, &w1, x[5], x[5]); + z[10] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[9]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[8]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[7]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[6]); + z[11] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[10]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[9]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[8]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[7]); + word3_muladd(&w2, &w1, &w0, x[6], x[6]); + z[12] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[9]); + word3_muladd_2(&w0, &w2, &w1, x[5], x[8]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[7]); + z[13] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[9]); + word3_muladd_2(&w1, &w0, &w2, x[6], x[8]); + word3_muladd(&w1, &w0, &w2, x[7], x[7]); + z[14] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[10]); + word3_muladd_2(&w2, &w1, &w0, x[6], x[9]); + word3_muladd_2(&w2, &w1, &w0, x[7], x[8]); + z[15] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[5], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[7], x[9]); + word3_muladd(&w0, &w2, &w1, x[8], x[8]); + z[16] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[6], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[7], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[8], x[9]); + z[17] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[16]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[6], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[7], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[8], x[10]); + word3_muladd(&w2, &w1, &w0, x[9], x[9]); + z[18] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[5], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[7], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[8], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[9], x[10]); + z[19] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[6], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[7], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[8], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[9], x[11]); + word3_muladd(&w1, &w0, &w2, x[10], x[10]); + z[20] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[0], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[1], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[16]); + word3_muladd_2(&w2, &w1, &w0, x[6], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[7], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[8], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[9], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[11]); + z[21] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[0], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[1], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[2], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[5], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[7], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[8], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[9], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[12]); + word3_muladd(&w0, &w2, &w1, x[11], x[11]); + z[22] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[0], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[1], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[2], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[3], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[6], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[7], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[8], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[9], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[12]); + z[23] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[1], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[2], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[3], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[4], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[6], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[7], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[8], x[16]); + word3_muladd_2(&w2, &w1, &w0, x[9], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[13]); + word3_muladd(&w2, &w1, &w0, x[12], x[12]); + z[24] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[2], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[3], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[4], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[5], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[7], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[8], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[9], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[13]); + z[25] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[3], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[4], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[5], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[6], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[7], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[8], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[9], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[14]); + word3_muladd(&w1, &w0, &w2, x[13], x[13]); + z[26] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[4], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[5], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[6], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[7], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[8], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[9], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[16]); + word3_muladd_2(&w2, &w1, &w0, x[12], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[13], x[14]); + z[27] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[5], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[6], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[7], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[8], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[9], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[13], x[15]); + word3_muladd(&w0, &w2, &w1, x[14], x[14]); + z[28] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[6], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[7], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[8], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[9], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[13], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[14], x[15]); + z[29] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[7], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[8], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[9], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[12], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[13], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[14], x[16]); + word3_muladd(&w2, &w1, &w0, x[15], x[15]); + z[30] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[8], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[9], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[13], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[14], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[15], x[16]); + z[31] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[9], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[13], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[14], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[15], x[17]); + word3_muladd(&w1, &w0, &w2, x[16], x[16]); + z[32] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[10], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[12], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[13], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[14], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[15], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[16], x[17]); + z[33] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[11], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[13], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[14], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[15], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[16], x[18]); + word3_muladd(&w0, &w2, &w1, x[17], x[17]); + z[34] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[12], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[13], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[14], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[15], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[16], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[17], x[18]); + z[35] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[13], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[14], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[15], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[16], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[17], x[19]); + word3_muladd(&w2, &w1, &w0, x[18], x[18]); + z[36] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[14], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[15], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[16], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[17], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[18], x[19]); + z[37] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[15], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[16], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[17], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[18], x[20]); + word3_muladd(&w1, &w0, &w2, x[19], x[19]); + z[38] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[16], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[17], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[18], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[19], x[20]); + z[39] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[17], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[18], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[19], x[21]); + word3_muladd(&w0, &w2, &w1, x[20], x[20]); + z[40] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[18], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[19], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[20], x[21]); + z[41] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[19], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[20], x[22]); + word3_muladd(&w2, &w1, &w0, x[21], x[21]); + z[42] = w0; + w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[20], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[21], x[22]); + z[43] = w1; + w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[21], x[23]); + word3_muladd(&w1, &w0, &w2, x[22], x[22]); + z[44] = w2; + w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[22], x[23]); + z[45] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[23], x[23]); + z[46] = w1; + z[47] = w2; +} + +/* + * Comba 24x24 Multiplication + */ +void bigint_comba_mul24(word z[48], const word x[24], const word y[24]) { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[0]); + z[0] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[1]); + word3_muladd(&w0, &w2, &w1, x[1], y[0]); + z[1] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[2]); + word3_muladd(&w1, &w0, &w2, x[1], y[1]); + word3_muladd(&w1, &w0, &w2, x[2], y[0]); + z[2] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[3]); + word3_muladd(&w2, &w1, &w0, x[1], y[2]); + word3_muladd(&w2, &w1, &w0, x[2], y[1]); + word3_muladd(&w2, &w1, &w0, x[3], y[0]); + z[3] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[4]); + word3_muladd(&w0, &w2, &w1, x[1], y[3]); + word3_muladd(&w0, &w2, &w1, x[2], y[2]); + word3_muladd(&w0, &w2, &w1, x[3], y[1]); + word3_muladd(&w0, &w2, &w1, x[4], y[0]); + z[4] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[5]); + word3_muladd(&w1, &w0, &w2, x[1], y[4]); + word3_muladd(&w1, &w0, &w2, x[2], y[3]); + word3_muladd(&w1, &w0, &w2, x[3], y[2]); + word3_muladd(&w1, &w0, &w2, x[4], y[1]); + word3_muladd(&w1, &w0, &w2, x[5], y[0]); + z[5] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[6]); + word3_muladd(&w2, &w1, &w0, x[1], y[5]); + word3_muladd(&w2, &w1, &w0, x[2], y[4]); + word3_muladd(&w2, &w1, &w0, x[3], y[3]); + word3_muladd(&w2, &w1, &w0, x[4], y[2]); + word3_muladd(&w2, &w1, &w0, x[5], y[1]); + word3_muladd(&w2, &w1, &w0, x[6], y[0]); + z[6] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[7]); + word3_muladd(&w0, &w2, &w1, x[1], y[6]); + word3_muladd(&w0, &w2, &w1, x[2], y[5]); + word3_muladd(&w0, &w2, &w1, x[3], y[4]); + word3_muladd(&w0, &w2, &w1, x[4], y[3]); + word3_muladd(&w0, &w2, &w1, x[5], y[2]); + word3_muladd(&w0, &w2, &w1, x[6], y[1]); + word3_muladd(&w0, &w2, &w1, x[7], y[0]); + z[7] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[8]); + word3_muladd(&w1, &w0, &w2, x[1], y[7]); + word3_muladd(&w1, &w0, &w2, x[2], y[6]); + word3_muladd(&w1, &w0, &w2, x[3], y[5]); + word3_muladd(&w1, &w0, &w2, x[4], y[4]); + word3_muladd(&w1, &w0, &w2, x[5], y[3]); + word3_muladd(&w1, &w0, &w2, x[6], y[2]); + word3_muladd(&w1, &w0, &w2, x[7], y[1]); + word3_muladd(&w1, &w0, &w2, x[8], y[0]); + z[8] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[9]); + word3_muladd(&w2, &w1, &w0, x[1], y[8]); + word3_muladd(&w2, &w1, &w0, x[2], y[7]); + word3_muladd(&w2, &w1, &w0, x[3], y[6]); + word3_muladd(&w2, &w1, &w0, x[4], y[5]); + word3_muladd(&w2, &w1, &w0, x[5], y[4]); + word3_muladd(&w2, &w1, &w0, x[6], y[3]); + word3_muladd(&w2, &w1, &w0, x[7], y[2]); + word3_muladd(&w2, &w1, &w0, x[8], y[1]); + word3_muladd(&w2, &w1, &w0, x[9], y[0]); + z[9] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[10]); + word3_muladd(&w0, &w2, &w1, x[1], y[9]); + word3_muladd(&w0, &w2, &w1, x[2], y[8]); + word3_muladd(&w0, &w2, &w1, x[3], y[7]); + word3_muladd(&w0, &w2, &w1, x[4], y[6]); + word3_muladd(&w0, &w2, &w1, x[5], y[5]); + word3_muladd(&w0, &w2, &w1, x[6], y[4]); + word3_muladd(&w0, &w2, &w1, x[7], y[3]); + word3_muladd(&w0, &w2, &w1, x[8], y[2]); + word3_muladd(&w0, &w2, &w1, x[9], y[1]); + word3_muladd(&w0, &w2, &w1, x[10], y[0]); + z[10] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[11]); + word3_muladd(&w1, &w0, &w2, x[1], y[10]); + word3_muladd(&w1, &w0, &w2, x[2], y[9]); + word3_muladd(&w1, &w0, &w2, x[3], y[8]); + word3_muladd(&w1, &w0, &w2, x[4], y[7]); + word3_muladd(&w1, &w0, &w2, x[5], y[6]); + word3_muladd(&w1, &w0, &w2, x[6], y[5]); + word3_muladd(&w1, &w0, &w2, x[7], y[4]); + word3_muladd(&w1, &w0, &w2, x[8], y[3]); + word3_muladd(&w1, &w0, &w2, x[9], y[2]); + word3_muladd(&w1, &w0, &w2, x[10], y[1]); + word3_muladd(&w1, &w0, &w2, x[11], y[0]); + z[11] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[12]); + word3_muladd(&w2, &w1, &w0, x[1], y[11]); + word3_muladd(&w2, &w1, &w0, x[2], y[10]); + word3_muladd(&w2, &w1, &w0, x[3], y[9]); + word3_muladd(&w2, &w1, &w0, x[4], y[8]); + word3_muladd(&w2, &w1, &w0, x[5], y[7]); + word3_muladd(&w2, &w1, &w0, x[6], y[6]); + word3_muladd(&w2, &w1, &w0, x[7], y[5]); + word3_muladd(&w2, &w1, &w0, x[8], y[4]); + word3_muladd(&w2, &w1, &w0, x[9], y[3]); + word3_muladd(&w2, &w1, &w0, x[10], y[2]); + word3_muladd(&w2, &w1, &w0, x[11], y[1]); + word3_muladd(&w2, &w1, &w0, x[12], y[0]); + z[12] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[13]); + word3_muladd(&w0, &w2, &w1, x[1], y[12]); + word3_muladd(&w0, &w2, &w1, x[2], y[11]); + word3_muladd(&w0, &w2, &w1, x[3], y[10]); + word3_muladd(&w0, &w2, &w1, x[4], y[9]); + word3_muladd(&w0, &w2, &w1, x[5], y[8]); + word3_muladd(&w0, &w2, &w1, x[6], y[7]); + word3_muladd(&w0, &w2, &w1, x[7], y[6]); + word3_muladd(&w0, &w2, &w1, x[8], y[5]); + word3_muladd(&w0, &w2, &w1, x[9], y[4]); + word3_muladd(&w0, &w2, &w1, x[10], y[3]); + word3_muladd(&w0, &w2, &w1, x[11], y[2]); + word3_muladd(&w0, &w2, &w1, x[12], y[1]); + word3_muladd(&w0, &w2, &w1, x[13], y[0]); + z[13] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[14]); + word3_muladd(&w1, &w0, &w2, x[1], y[13]); + word3_muladd(&w1, &w0, &w2, x[2], y[12]); + word3_muladd(&w1, &w0, &w2, x[3], y[11]); + word3_muladd(&w1, &w0, &w2, x[4], y[10]); + word3_muladd(&w1, &w0, &w2, x[5], y[9]); + word3_muladd(&w1, &w0, &w2, x[6], y[8]); + word3_muladd(&w1, &w0, &w2, x[7], y[7]); + word3_muladd(&w1, &w0, &w2, x[8], y[6]); + word3_muladd(&w1, &w0, &w2, x[9], y[5]); + word3_muladd(&w1, &w0, &w2, x[10], y[4]); + word3_muladd(&w1, &w0, &w2, x[11], y[3]); + word3_muladd(&w1, &w0, &w2, x[12], y[2]); + word3_muladd(&w1, &w0, &w2, x[13], y[1]); + word3_muladd(&w1, &w0, &w2, x[14], y[0]); + z[14] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[15]); + word3_muladd(&w2, &w1, &w0, x[1], y[14]); + word3_muladd(&w2, &w1, &w0, x[2], y[13]); + word3_muladd(&w2, &w1, &w0, x[3], y[12]); + word3_muladd(&w2, &w1, &w0, x[4], y[11]); + word3_muladd(&w2, &w1, &w0, x[5], y[10]); + word3_muladd(&w2, &w1, &w0, x[6], y[9]); + word3_muladd(&w2, &w1, &w0, x[7], y[8]); + word3_muladd(&w2, &w1, &w0, x[8], y[7]); + word3_muladd(&w2, &w1, &w0, x[9], y[6]); + word3_muladd(&w2, &w1, &w0, x[10], y[5]); + word3_muladd(&w2, &w1, &w0, x[11], y[4]); + word3_muladd(&w2, &w1, &w0, x[12], y[3]); + word3_muladd(&w2, &w1, &w0, x[13], y[2]); + word3_muladd(&w2, &w1, &w0, x[14], y[1]); + word3_muladd(&w2, &w1, &w0, x[15], y[0]); + z[15] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[16]); + word3_muladd(&w0, &w2, &w1, x[1], y[15]); + word3_muladd(&w0, &w2, &w1, x[2], y[14]); + word3_muladd(&w0, &w2, &w1, x[3], y[13]); + word3_muladd(&w0, &w2, &w1, x[4], y[12]); + word3_muladd(&w0, &w2, &w1, x[5], y[11]); + word3_muladd(&w0, &w2, &w1, x[6], y[10]); + word3_muladd(&w0, &w2, &w1, x[7], y[9]); + word3_muladd(&w0, &w2, &w1, x[8], y[8]); + word3_muladd(&w0, &w2, &w1, x[9], y[7]); + word3_muladd(&w0, &w2, &w1, x[10], y[6]); + word3_muladd(&w0, &w2, &w1, x[11], y[5]); + word3_muladd(&w0, &w2, &w1, x[12], y[4]); + word3_muladd(&w0, &w2, &w1, x[13], y[3]); + word3_muladd(&w0, &w2, &w1, x[14], y[2]); + word3_muladd(&w0, &w2, &w1, x[15], y[1]); + word3_muladd(&w0, &w2, &w1, x[16], y[0]); + z[16] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[17]); + word3_muladd(&w1, &w0, &w2, x[1], y[16]); + word3_muladd(&w1, &w0, &w2, x[2], y[15]); + word3_muladd(&w1, &w0, &w2, x[3], y[14]); + word3_muladd(&w1, &w0, &w2, x[4], y[13]); + word3_muladd(&w1, &w0, &w2, x[5], y[12]); + word3_muladd(&w1, &w0, &w2, x[6], y[11]); + word3_muladd(&w1, &w0, &w2, x[7], y[10]); + word3_muladd(&w1, &w0, &w2, x[8], y[9]); + word3_muladd(&w1, &w0, &w2, x[9], y[8]); + word3_muladd(&w1, &w0, &w2, x[10], y[7]); + word3_muladd(&w1, &w0, &w2, x[11], y[6]); + word3_muladd(&w1, &w0, &w2, x[12], y[5]); + word3_muladd(&w1, &w0, &w2, x[13], y[4]); + word3_muladd(&w1, &w0, &w2, x[14], y[3]); + word3_muladd(&w1, &w0, &w2, x[15], y[2]); + word3_muladd(&w1, &w0, &w2, x[16], y[1]); + word3_muladd(&w1, &w0, &w2, x[17], y[0]); + z[17] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[18]); + word3_muladd(&w2, &w1, &w0, x[1], y[17]); + word3_muladd(&w2, &w1, &w0, x[2], y[16]); + word3_muladd(&w2, &w1, &w0, x[3], y[15]); + word3_muladd(&w2, &w1, &w0, x[4], y[14]); + word3_muladd(&w2, &w1, &w0, x[5], y[13]); + word3_muladd(&w2, &w1, &w0, x[6], y[12]); + word3_muladd(&w2, &w1, &w0, x[7], y[11]); + word3_muladd(&w2, &w1, &w0, x[8], y[10]); + word3_muladd(&w2, &w1, &w0, x[9], y[9]); + word3_muladd(&w2, &w1, &w0, x[10], y[8]); + word3_muladd(&w2, &w1, &w0, x[11], y[7]); + word3_muladd(&w2, &w1, &w0, x[12], y[6]); + word3_muladd(&w2, &w1, &w0, x[13], y[5]); + word3_muladd(&w2, &w1, &w0, x[14], y[4]); + word3_muladd(&w2, &w1, &w0, x[15], y[3]); + word3_muladd(&w2, &w1, &w0, x[16], y[2]); + word3_muladd(&w2, &w1, &w0, x[17], y[1]); + word3_muladd(&w2, &w1, &w0, x[18], y[0]); + z[18] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[19]); + word3_muladd(&w0, &w2, &w1, x[1], y[18]); + word3_muladd(&w0, &w2, &w1, x[2], y[17]); + word3_muladd(&w0, &w2, &w1, x[3], y[16]); + word3_muladd(&w0, &w2, &w1, x[4], y[15]); + word3_muladd(&w0, &w2, &w1, x[5], y[14]); + word3_muladd(&w0, &w2, &w1, x[6], y[13]); + word3_muladd(&w0, &w2, &w1, x[7], y[12]); + word3_muladd(&w0, &w2, &w1, x[8], y[11]); + word3_muladd(&w0, &w2, &w1, x[9], y[10]); + word3_muladd(&w0, &w2, &w1, x[10], y[9]); + word3_muladd(&w0, &w2, &w1, x[11], y[8]); + word3_muladd(&w0, &w2, &w1, x[12], y[7]); + word3_muladd(&w0, &w2, &w1, x[13], y[6]); + word3_muladd(&w0, &w2, &w1, x[14], y[5]); + word3_muladd(&w0, &w2, &w1, x[15], y[4]); + word3_muladd(&w0, &w2, &w1, x[16], y[3]); + word3_muladd(&w0, &w2, &w1, x[17], y[2]); + word3_muladd(&w0, &w2, &w1, x[18], y[1]); + word3_muladd(&w0, &w2, &w1, x[19], y[0]); + z[19] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[20]); + word3_muladd(&w1, &w0, &w2, x[1], y[19]); + word3_muladd(&w1, &w0, &w2, x[2], y[18]); + word3_muladd(&w1, &w0, &w2, x[3], y[17]); + word3_muladd(&w1, &w0, &w2, x[4], y[16]); + word3_muladd(&w1, &w0, &w2, x[5], y[15]); + word3_muladd(&w1, &w0, &w2, x[6], y[14]); + word3_muladd(&w1, &w0, &w2, x[7], y[13]); + word3_muladd(&w1, &w0, &w2, x[8], y[12]); + word3_muladd(&w1, &w0, &w2, x[9], y[11]); + word3_muladd(&w1, &w0, &w2, x[10], y[10]); + word3_muladd(&w1, &w0, &w2, x[11], y[9]); + word3_muladd(&w1, &w0, &w2, x[12], y[8]); + word3_muladd(&w1, &w0, &w2, x[13], y[7]); + word3_muladd(&w1, &w0, &w2, x[14], y[6]); + word3_muladd(&w1, &w0, &w2, x[15], y[5]); + word3_muladd(&w1, &w0, &w2, x[16], y[4]); + word3_muladd(&w1, &w0, &w2, x[17], y[3]); + word3_muladd(&w1, &w0, &w2, x[18], y[2]); + word3_muladd(&w1, &w0, &w2, x[19], y[1]); + word3_muladd(&w1, &w0, &w2, x[20], y[0]); + z[20] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[0], y[21]); + word3_muladd(&w2, &w1, &w0, x[1], y[20]); + word3_muladd(&w2, &w1, &w0, x[2], y[19]); + word3_muladd(&w2, &w1, &w0, x[3], y[18]); + word3_muladd(&w2, &w1, &w0, x[4], y[17]); + word3_muladd(&w2, &w1, &w0, x[5], y[16]); + word3_muladd(&w2, &w1, &w0, x[6], y[15]); + word3_muladd(&w2, &w1, &w0, x[7], y[14]); + word3_muladd(&w2, &w1, &w0, x[8], y[13]); + word3_muladd(&w2, &w1, &w0, x[9], y[12]); + word3_muladd(&w2, &w1, &w0, x[10], y[11]); + word3_muladd(&w2, &w1, &w0, x[11], y[10]); + word3_muladd(&w2, &w1, &w0, x[12], y[9]); + word3_muladd(&w2, &w1, &w0, x[13], y[8]); + word3_muladd(&w2, &w1, &w0, x[14], y[7]); + word3_muladd(&w2, &w1, &w0, x[15], y[6]); + word3_muladd(&w2, &w1, &w0, x[16], y[5]); + word3_muladd(&w2, &w1, &w0, x[17], y[4]); + word3_muladd(&w2, &w1, &w0, x[18], y[3]); + word3_muladd(&w2, &w1, &w0, x[19], y[2]); + word3_muladd(&w2, &w1, &w0, x[20], y[1]); + word3_muladd(&w2, &w1, &w0, x[21], y[0]); + z[21] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[0], y[22]); + word3_muladd(&w0, &w2, &w1, x[1], y[21]); + word3_muladd(&w0, &w2, &w1, x[2], y[20]); + word3_muladd(&w0, &w2, &w1, x[3], y[19]); + word3_muladd(&w0, &w2, &w1, x[4], y[18]); + word3_muladd(&w0, &w2, &w1, x[5], y[17]); + word3_muladd(&w0, &w2, &w1, x[6], y[16]); + word3_muladd(&w0, &w2, &w1, x[7], y[15]); + word3_muladd(&w0, &w2, &w1, x[8], y[14]); + word3_muladd(&w0, &w2, &w1, x[9], y[13]); + word3_muladd(&w0, &w2, &w1, x[10], y[12]); + word3_muladd(&w0, &w2, &w1, x[11], y[11]); + word3_muladd(&w0, &w2, &w1, x[12], y[10]); + word3_muladd(&w0, &w2, &w1, x[13], y[9]); + word3_muladd(&w0, &w2, &w1, x[14], y[8]); + word3_muladd(&w0, &w2, &w1, x[15], y[7]); + word3_muladd(&w0, &w2, &w1, x[16], y[6]); + word3_muladd(&w0, &w2, &w1, x[17], y[5]); + word3_muladd(&w0, &w2, &w1, x[18], y[4]); + word3_muladd(&w0, &w2, &w1, x[19], y[3]); + word3_muladd(&w0, &w2, &w1, x[20], y[2]); + word3_muladd(&w0, &w2, &w1, x[21], y[1]); + word3_muladd(&w0, &w2, &w1, x[22], y[0]); + z[22] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[0], y[23]); + word3_muladd(&w1, &w0, &w2, x[1], y[22]); + word3_muladd(&w1, &w0, &w2, x[2], y[21]); + word3_muladd(&w1, &w0, &w2, x[3], y[20]); + word3_muladd(&w1, &w0, &w2, x[4], y[19]); + word3_muladd(&w1, &w0, &w2, x[5], y[18]); + word3_muladd(&w1, &w0, &w2, x[6], y[17]); + word3_muladd(&w1, &w0, &w2, x[7], y[16]); + word3_muladd(&w1, &w0, &w2, x[8], y[15]); + word3_muladd(&w1, &w0, &w2, x[9], y[14]); + word3_muladd(&w1, &w0, &w2, x[10], y[13]); + word3_muladd(&w1, &w0, &w2, x[11], y[12]); + word3_muladd(&w1, &w0, &w2, x[12], y[11]); + word3_muladd(&w1, &w0, &w2, x[13], y[10]); + word3_muladd(&w1, &w0, &w2, x[14], y[9]); + word3_muladd(&w1, &w0, &w2, x[15], y[8]); + word3_muladd(&w1, &w0, &w2, x[16], y[7]); + word3_muladd(&w1, &w0, &w2, x[17], y[6]); + word3_muladd(&w1, &w0, &w2, x[18], y[5]); + word3_muladd(&w1, &w0, &w2, x[19], y[4]); + word3_muladd(&w1, &w0, &w2, x[20], y[3]); + word3_muladd(&w1, &w0, &w2, x[21], y[2]); + word3_muladd(&w1, &w0, &w2, x[22], y[1]); + word3_muladd(&w1, &w0, &w2, x[23], y[0]); + z[23] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[1], y[23]); + word3_muladd(&w2, &w1, &w0, x[2], y[22]); + word3_muladd(&w2, &w1, &w0, x[3], y[21]); + word3_muladd(&w2, &w1, &w0, x[4], y[20]); + word3_muladd(&w2, &w1, &w0, x[5], y[19]); + word3_muladd(&w2, &w1, &w0, x[6], y[18]); + word3_muladd(&w2, &w1, &w0, x[7], y[17]); + word3_muladd(&w2, &w1, &w0, x[8], y[16]); + word3_muladd(&w2, &w1, &w0, x[9], y[15]); + word3_muladd(&w2, &w1, &w0, x[10], y[14]); + word3_muladd(&w2, &w1, &w0, x[11], y[13]); + word3_muladd(&w2, &w1, &w0, x[12], y[12]); + word3_muladd(&w2, &w1, &w0, x[13], y[11]); + word3_muladd(&w2, &w1, &w0, x[14], y[10]); + word3_muladd(&w2, &w1, &w0, x[15], y[9]); + word3_muladd(&w2, &w1, &w0, x[16], y[8]); + word3_muladd(&w2, &w1, &w0, x[17], y[7]); + word3_muladd(&w2, &w1, &w0, x[18], y[6]); + word3_muladd(&w2, &w1, &w0, x[19], y[5]); + word3_muladd(&w2, &w1, &w0, x[20], y[4]); + word3_muladd(&w2, &w1, &w0, x[21], y[3]); + word3_muladd(&w2, &w1, &w0, x[22], y[2]); + word3_muladd(&w2, &w1, &w0, x[23], y[1]); + z[24] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[2], y[23]); + word3_muladd(&w0, &w2, &w1, x[3], y[22]); + word3_muladd(&w0, &w2, &w1, x[4], y[21]); + word3_muladd(&w0, &w2, &w1, x[5], y[20]); + word3_muladd(&w0, &w2, &w1, x[6], y[19]); + word3_muladd(&w0, &w2, &w1, x[7], y[18]); + word3_muladd(&w0, &w2, &w1, x[8], y[17]); + word3_muladd(&w0, &w2, &w1, x[9], y[16]); + word3_muladd(&w0, &w2, &w1, x[10], y[15]); + word3_muladd(&w0, &w2, &w1, x[11], y[14]); + word3_muladd(&w0, &w2, &w1, x[12], y[13]); + word3_muladd(&w0, &w2, &w1, x[13], y[12]); + word3_muladd(&w0, &w2, &w1, x[14], y[11]); + word3_muladd(&w0, &w2, &w1, x[15], y[10]); + word3_muladd(&w0, &w2, &w1, x[16], y[9]); + word3_muladd(&w0, &w2, &w1, x[17], y[8]); + word3_muladd(&w0, &w2, &w1, x[18], y[7]); + word3_muladd(&w0, &w2, &w1, x[19], y[6]); + word3_muladd(&w0, &w2, &w1, x[20], y[5]); + word3_muladd(&w0, &w2, &w1, x[21], y[4]); + word3_muladd(&w0, &w2, &w1, x[22], y[3]); + word3_muladd(&w0, &w2, &w1, x[23], y[2]); + z[25] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[3], y[23]); + word3_muladd(&w1, &w0, &w2, x[4], y[22]); + word3_muladd(&w1, &w0, &w2, x[5], y[21]); + word3_muladd(&w1, &w0, &w2, x[6], y[20]); + word3_muladd(&w1, &w0, &w2, x[7], y[19]); + word3_muladd(&w1, &w0, &w2, x[8], y[18]); + word3_muladd(&w1, &w0, &w2, x[9], y[17]); + word3_muladd(&w1, &w0, &w2, x[10], y[16]); + word3_muladd(&w1, &w0, &w2, x[11], y[15]); + word3_muladd(&w1, &w0, &w2, x[12], y[14]); + word3_muladd(&w1, &w0, &w2, x[13], y[13]); + word3_muladd(&w1, &w0, &w2, x[14], y[12]); + word3_muladd(&w1, &w0, &w2, x[15], y[11]); + word3_muladd(&w1, &w0, &w2, x[16], y[10]); + word3_muladd(&w1, &w0, &w2, x[17], y[9]); + word3_muladd(&w1, &w0, &w2, x[18], y[8]); + word3_muladd(&w1, &w0, &w2, x[19], y[7]); + word3_muladd(&w1, &w0, &w2, x[20], y[6]); + word3_muladd(&w1, &w0, &w2, x[21], y[5]); + word3_muladd(&w1, &w0, &w2, x[22], y[4]); + word3_muladd(&w1, &w0, &w2, x[23], y[3]); + z[26] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[4], y[23]); + word3_muladd(&w2, &w1, &w0, x[5], y[22]); + word3_muladd(&w2, &w1, &w0, x[6], y[21]); + word3_muladd(&w2, &w1, &w0, x[7], y[20]); + word3_muladd(&w2, &w1, &w0, x[8], y[19]); + word3_muladd(&w2, &w1, &w0, x[9], y[18]); + word3_muladd(&w2, &w1, &w0, x[10], y[17]); + word3_muladd(&w2, &w1, &w0, x[11], y[16]); + word3_muladd(&w2, &w1, &w0, x[12], y[15]); + word3_muladd(&w2, &w1, &w0, x[13], y[14]); + word3_muladd(&w2, &w1, &w0, x[14], y[13]); + word3_muladd(&w2, &w1, &w0, x[15], y[12]); + word3_muladd(&w2, &w1, &w0, x[16], y[11]); + word3_muladd(&w2, &w1, &w0, x[17], y[10]); + word3_muladd(&w2, &w1, &w0, x[18], y[9]); + word3_muladd(&w2, &w1, &w0, x[19], y[8]); + word3_muladd(&w2, &w1, &w0, x[20], y[7]); + word3_muladd(&w2, &w1, &w0, x[21], y[6]); + word3_muladd(&w2, &w1, &w0, x[22], y[5]); + word3_muladd(&w2, &w1, &w0, x[23], y[4]); + z[27] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[5], y[23]); + word3_muladd(&w0, &w2, &w1, x[6], y[22]); + word3_muladd(&w0, &w2, &w1, x[7], y[21]); + word3_muladd(&w0, &w2, &w1, x[8], y[20]); + word3_muladd(&w0, &w2, &w1, x[9], y[19]); + word3_muladd(&w0, &w2, &w1, x[10], y[18]); + word3_muladd(&w0, &w2, &w1, x[11], y[17]); + word3_muladd(&w0, &w2, &w1, x[12], y[16]); + word3_muladd(&w0, &w2, &w1, x[13], y[15]); + word3_muladd(&w0, &w2, &w1, x[14], y[14]); + word3_muladd(&w0, &w2, &w1, x[15], y[13]); + word3_muladd(&w0, &w2, &w1, x[16], y[12]); + word3_muladd(&w0, &w2, &w1, x[17], y[11]); + word3_muladd(&w0, &w2, &w1, x[18], y[10]); + word3_muladd(&w0, &w2, &w1, x[19], y[9]); + word3_muladd(&w0, &w2, &w1, x[20], y[8]); + word3_muladd(&w0, &w2, &w1, x[21], y[7]); + word3_muladd(&w0, &w2, &w1, x[22], y[6]); + word3_muladd(&w0, &w2, &w1, x[23], y[5]); + z[28] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[6], y[23]); + word3_muladd(&w1, &w0, &w2, x[7], y[22]); + word3_muladd(&w1, &w0, &w2, x[8], y[21]); + word3_muladd(&w1, &w0, &w2, x[9], y[20]); + word3_muladd(&w1, &w0, &w2, x[10], y[19]); + word3_muladd(&w1, &w0, &w2, x[11], y[18]); + word3_muladd(&w1, &w0, &w2, x[12], y[17]); + word3_muladd(&w1, &w0, &w2, x[13], y[16]); + word3_muladd(&w1, &w0, &w2, x[14], y[15]); + word3_muladd(&w1, &w0, &w2, x[15], y[14]); + word3_muladd(&w1, &w0, &w2, x[16], y[13]); + word3_muladd(&w1, &w0, &w2, x[17], y[12]); + word3_muladd(&w1, &w0, &w2, x[18], y[11]); + word3_muladd(&w1, &w0, &w2, x[19], y[10]); + word3_muladd(&w1, &w0, &w2, x[20], y[9]); + word3_muladd(&w1, &w0, &w2, x[21], y[8]); + word3_muladd(&w1, &w0, &w2, x[22], y[7]); + word3_muladd(&w1, &w0, &w2, x[23], y[6]); + z[29] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[7], y[23]); + word3_muladd(&w2, &w1, &w0, x[8], y[22]); + word3_muladd(&w2, &w1, &w0, x[9], y[21]); + word3_muladd(&w2, &w1, &w0, x[10], y[20]); + word3_muladd(&w2, &w1, &w0, x[11], y[19]); + word3_muladd(&w2, &w1, &w0, x[12], y[18]); + word3_muladd(&w2, &w1, &w0, x[13], y[17]); + word3_muladd(&w2, &w1, &w0, x[14], y[16]); + word3_muladd(&w2, &w1, &w0, x[15], y[15]); + word3_muladd(&w2, &w1, &w0, x[16], y[14]); + word3_muladd(&w2, &w1, &w0, x[17], y[13]); + word3_muladd(&w2, &w1, &w0, x[18], y[12]); + word3_muladd(&w2, &w1, &w0, x[19], y[11]); + word3_muladd(&w2, &w1, &w0, x[20], y[10]); + word3_muladd(&w2, &w1, &w0, x[21], y[9]); + word3_muladd(&w2, &w1, &w0, x[22], y[8]); + word3_muladd(&w2, &w1, &w0, x[23], y[7]); + z[30] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[8], y[23]); + word3_muladd(&w0, &w2, &w1, x[9], y[22]); + word3_muladd(&w0, &w2, &w1, x[10], y[21]); + word3_muladd(&w0, &w2, &w1, x[11], y[20]); + word3_muladd(&w0, &w2, &w1, x[12], y[19]); + word3_muladd(&w0, &w2, &w1, x[13], y[18]); + word3_muladd(&w0, &w2, &w1, x[14], y[17]); + word3_muladd(&w0, &w2, &w1, x[15], y[16]); + word3_muladd(&w0, &w2, &w1, x[16], y[15]); + word3_muladd(&w0, &w2, &w1, x[17], y[14]); + word3_muladd(&w0, &w2, &w1, x[18], y[13]); + word3_muladd(&w0, &w2, &w1, x[19], y[12]); + word3_muladd(&w0, &w2, &w1, x[20], y[11]); + word3_muladd(&w0, &w2, &w1, x[21], y[10]); + word3_muladd(&w0, &w2, &w1, x[22], y[9]); + word3_muladd(&w0, &w2, &w1, x[23], y[8]); + z[31] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[9], y[23]); + word3_muladd(&w1, &w0, &w2, x[10], y[22]); + word3_muladd(&w1, &w0, &w2, x[11], y[21]); + word3_muladd(&w1, &w0, &w2, x[12], y[20]); + word3_muladd(&w1, &w0, &w2, x[13], y[19]); + word3_muladd(&w1, &w0, &w2, x[14], y[18]); + word3_muladd(&w1, &w0, &w2, x[15], y[17]); + word3_muladd(&w1, &w0, &w2, x[16], y[16]); + word3_muladd(&w1, &w0, &w2, x[17], y[15]); + word3_muladd(&w1, &w0, &w2, x[18], y[14]); + word3_muladd(&w1, &w0, &w2, x[19], y[13]); + word3_muladd(&w1, &w0, &w2, x[20], y[12]); + word3_muladd(&w1, &w0, &w2, x[21], y[11]); + word3_muladd(&w1, &w0, &w2, x[22], y[10]); + word3_muladd(&w1, &w0, &w2, x[23], y[9]); + z[32] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[10], y[23]); + word3_muladd(&w2, &w1, &w0, x[11], y[22]); + word3_muladd(&w2, &w1, &w0, x[12], y[21]); + word3_muladd(&w2, &w1, &w0, x[13], y[20]); + word3_muladd(&w2, &w1, &w0, x[14], y[19]); + word3_muladd(&w2, &w1, &w0, x[15], y[18]); + word3_muladd(&w2, &w1, &w0, x[16], y[17]); + word3_muladd(&w2, &w1, &w0, x[17], y[16]); + word3_muladd(&w2, &w1, &w0, x[18], y[15]); + word3_muladd(&w2, &w1, &w0, x[19], y[14]); + word3_muladd(&w2, &w1, &w0, x[20], y[13]); + word3_muladd(&w2, &w1, &w0, x[21], y[12]); + word3_muladd(&w2, &w1, &w0, x[22], y[11]); + word3_muladd(&w2, &w1, &w0, x[23], y[10]); + z[33] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[11], y[23]); + word3_muladd(&w0, &w2, &w1, x[12], y[22]); + word3_muladd(&w0, &w2, &w1, x[13], y[21]); + word3_muladd(&w0, &w2, &w1, x[14], y[20]); + word3_muladd(&w0, &w2, &w1, x[15], y[19]); + word3_muladd(&w0, &w2, &w1, x[16], y[18]); + word3_muladd(&w0, &w2, &w1, x[17], y[17]); + word3_muladd(&w0, &w2, &w1, x[18], y[16]); + word3_muladd(&w0, &w2, &w1, x[19], y[15]); + word3_muladd(&w0, &w2, &w1, x[20], y[14]); + word3_muladd(&w0, &w2, &w1, x[21], y[13]); + word3_muladd(&w0, &w2, &w1, x[22], y[12]); + word3_muladd(&w0, &w2, &w1, x[23], y[11]); + z[34] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[12], y[23]); + word3_muladd(&w1, &w0, &w2, x[13], y[22]); + word3_muladd(&w1, &w0, &w2, x[14], y[21]); + word3_muladd(&w1, &w0, &w2, x[15], y[20]); + word3_muladd(&w1, &w0, &w2, x[16], y[19]); + word3_muladd(&w1, &w0, &w2, x[17], y[18]); + word3_muladd(&w1, &w0, &w2, x[18], y[17]); + word3_muladd(&w1, &w0, &w2, x[19], y[16]); + word3_muladd(&w1, &w0, &w2, x[20], y[15]); + word3_muladd(&w1, &w0, &w2, x[21], y[14]); + word3_muladd(&w1, &w0, &w2, x[22], y[13]); + word3_muladd(&w1, &w0, &w2, x[23], y[12]); + z[35] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[13], y[23]); + word3_muladd(&w2, &w1, &w0, x[14], y[22]); + word3_muladd(&w2, &w1, &w0, x[15], y[21]); + word3_muladd(&w2, &w1, &w0, x[16], y[20]); + word3_muladd(&w2, &w1, &w0, x[17], y[19]); + word3_muladd(&w2, &w1, &w0, x[18], y[18]); + word3_muladd(&w2, &w1, &w0, x[19], y[17]); + word3_muladd(&w2, &w1, &w0, x[20], y[16]); + word3_muladd(&w2, &w1, &w0, x[21], y[15]); + word3_muladd(&w2, &w1, &w0, x[22], y[14]); + word3_muladd(&w2, &w1, &w0, x[23], y[13]); + z[36] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[14], y[23]); + word3_muladd(&w0, &w2, &w1, x[15], y[22]); + word3_muladd(&w0, &w2, &w1, x[16], y[21]); + word3_muladd(&w0, &w2, &w1, x[17], y[20]); + word3_muladd(&w0, &w2, &w1, x[18], y[19]); + word3_muladd(&w0, &w2, &w1, x[19], y[18]); + word3_muladd(&w0, &w2, &w1, x[20], y[17]); + word3_muladd(&w0, &w2, &w1, x[21], y[16]); + word3_muladd(&w0, &w2, &w1, x[22], y[15]); + word3_muladd(&w0, &w2, &w1, x[23], y[14]); + z[37] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[15], y[23]); + word3_muladd(&w1, &w0, &w2, x[16], y[22]); + word3_muladd(&w1, &w0, &w2, x[17], y[21]); + word3_muladd(&w1, &w0, &w2, x[18], y[20]); + word3_muladd(&w1, &w0, &w2, x[19], y[19]); + word3_muladd(&w1, &w0, &w2, x[20], y[18]); + word3_muladd(&w1, &w0, &w2, x[21], y[17]); + word3_muladd(&w1, &w0, &w2, x[22], y[16]); + word3_muladd(&w1, &w0, &w2, x[23], y[15]); + z[38] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[16], y[23]); + word3_muladd(&w2, &w1, &w0, x[17], y[22]); + word3_muladd(&w2, &w1, &w0, x[18], y[21]); + word3_muladd(&w2, &w1, &w0, x[19], y[20]); + word3_muladd(&w2, &w1, &w0, x[20], y[19]); + word3_muladd(&w2, &w1, &w0, x[21], y[18]); + word3_muladd(&w2, &w1, &w0, x[22], y[17]); + word3_muladd(&w2, &w1, &w0, x[23], y[16]); + z[39] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[17], y[23]); + word3_muladd(&w0, &w2, &w1, x[18], y[22]); + word3_muladd(&w0, &w2, &w1, x[19], y[21]); + word3_muladd(&w0, &w2, &w1, x[20], y[20]); + word3_muladd(&w0, &w2, &w1, x[21], y[19]); + word3_muladd(&w0, &w2, &w1, x[22], y[18]); + word3_muladd(&w0, &w2, &w1, x[23], y[17]); + z[40] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[18], y[23]); + word3_muladd(&w1, &w0, &w2, x[19], y[22]); + word3_muladd(&w1, &w0, &w2, x[20], y[21]); + word3_muladd(&w1, &w0, &w2, x[21], y[20]); + word3_muladd(&w1, &w0, &w2, x[22], y[19]); + word3_muladd(&w1, &w0, &w2, x[23], y[18]); + z[41] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[19], y[23]); + word3_muladd(&w2, &w1, &w0, x[20], y[22]); + word3_muladd(&w2, &w1, &w0, x[21], y[21]); + word3_muladd(&w2, &w1, &w0, x[22], y[20]); + word3_muladd(&w2, &w1, &w0, x[23], y[19]); + z[42] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[20], y[23]); + word3_muladd(&w0, &w2, &w1, x[21], y[22]); + word3_muladd(&w0, &w2, &w1, x[22], y[21]); + word3_muladd(&w0, &w2, &w1, x[23], y[20]); + z[43] = w1; + w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[21], y[23]); + word3_muladd(&w1, &w0, &w2, x[22], y[22]); + word3_muladd(&w1, &w0, &w2, x[23], y[21]); + z[44] = w2; + w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[22], y[23]); + word3_muladd(&w2, &w1, &w0, x[23], y[22]); + z[45] = w0; + w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[23], y[23]); + z[46] = w1; + z[47] = w2; +} + +} // namespace Botan +/* + * Multiplication and Squaring + * (C) 1999-2010,2018 Jack Lloyd + * 2016 Matthias Gierlings + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { @@ -13986,5032 +12323,5042 @@ const size_t KARATSUBA_MULTIPLY_THRESHOLD = 32; const size_t KARATSUBA_SQUARE_THRESHOLD = 32; /* -* Simple O(N^2) Multiplication -*/ -void basecase_mul(word z[], size_t z_size, - const word x[], size_t x_size, - const word y[], size_t y_size) - { - if(z_size < x_size + y_size) - throw Invalid_Argument("basecase_mul z_size too small"); + * Simple O(N^2) Multiplication + */ +void basecase_mul(word z[], size_t z_size, const word x[], size_t x_size, const word y[], + size_t y_size) { + if (z_size < x_size + y_size) throw Invalid_Argument("basecase_mul z_size too small"); - const size_t x_size_8 = x_size - (x_size % 8); + const size_t x_size_8 = x_size - (x_size % 8); - clear_mem(z, z_size); + clear_mem(z, z_size); - for(size_t i = 0; i != y_size; ++i) - { - const word y_i = y[i]; + for (size_t i = 0; i != y_size; ++i) { + const word y_i = y[i]; - word carry = 0; + word carry = 0; - for(size_t j = 0; j != x_size_8; j += 8) - carry = word8_madd3(z + i + j, x + j, y_i, carry); + for (size_t j = 0; j != x_size_8; j += 8) carry = word8_madd3(z + i + j, x + j, y_i, carry); - for(size_t j = x_size_8; j != x_size; ++j) - z[i+j] = word_madd3(x[j], y_i, z[i+j], &carry); - - z[x_size+i] = carry; - } - } - -void basecase_sqr(word z[], size_t z_size, - const word x[], size_t x_size) - { - if(z_size < 2*x_size) - throw Invalid_Argument("basecase_sqr z_size too small"); - - const size_t x_size_8 = x_size - (x_size % 8); - - clear_mem(z, z_size); - - for(size_t i = 0; i != x_size; ++i) - { - const word x_i = x[i]; - - word carry = 0; - - for(size_t j = 0; j != x_size_8; j += 8) - carry = word8_madd3(z + i + j, x + j, x_i, carry); - - for(size_t j = x_size_8; j != x_size; ++j) - z[i+j] = word_madd3(x[j], x_i, z[i+j], &carry); - - z[x_size+i] = carry; - } - } - -/* -* Karatsuba Multiplication Operation -*/ -void karatsuba_mul(word z[], const word x[], const word y[], size_t N, - word workspace[]) - { - if(N < KARATSUBA_MULTIPLY_THRESHOLD || N % 2) - { - switch(N) - { - case 6: - return bigint_comba_mul6(z, x, y); - case 8: - return bigint_comba_mul8(z, x, y); - case 9: - return bigint_comba_mul9(z, x, y); - case 16: - return bigint_comba_mul16(z, x, y); - case 24: - return bigint_comba_mul24(z, x, y); - default: - return basecase_mul(z, 2*N, x, N, y, N); - } - } - - const size_t N2 = N / 2; - - const word* x0 = x; - const word* x1 = x + N2; - const word* y0 = y; - const word* y1 = y + N2; - word* z0 = z; - word* z1 = z + N; - - word* ws0 = workspace; - word* ws1 = workspace + N; - - clear_mem(workspace, 2*N); - - /* - * If either of cmp0 or cmp1 is zero then z0 or z1 resp is zero here, - * resulting in a no-op - z0*z1 will be equal to zero so we don't need to do - * anything, clear_mem above already set the correct result. - * - * However we ignore the result of the comparisons and always perform the - * subtractions and recursively multiply to avoid the timing channel. - */ - - // First compute (X_lo - X_hi)*(Y_hi - Y_lo) - const auto cmp0 = bigint_sub_abs(z0, x0, x1, N2, workspace); - const auto cmp1 = bigint_sub_abs(z1, y1, y0, N2, workspace); - const auto neg_mask = ~(cmp0 ^ cmp1); - - karatsuba_mul(ws0, z0, z1, N2, ws1); - - // Compute X_lo * Y_lo - karatsuba_mul(z0, x0, y0, N2, ws1); - - // Compute X_hi * Y_hi - karatsuba_mul(z1, x1, y1, N2, ws1); - - const word ws_carry = bigint_add3_nc(ws1, z0, N, z1, N); - word z_carry = bigint_add2_nc(z + N2, N, ws1, N); - - z_carry += bigint_add2_nc(z + N + N2, N2, &ws_carry, 1); - bigint_add2_nc(z + N + N2, N2, &z_carry, 1); - - clear_mem(workspace + N, N2); - - bigint_cnd_add_or_sub(neg_mask, z + N2, workspace, 2*N-N2); - } - -/* -* Karatsuba Squaring Operation -*/ -void karatsuba_sqr(word z[], const word x[], size_t N, word workspace[]) - { - if(N < KARATSUBA_SQUARE_THRESHOLD || N % 2) - { - switch(N) - { - case 6: - return bigint_comba_sqr6(z, x); - case 8: - return bigint_comba_sqr8(z, x); - case 9: - return bigint_comba_sqr9(z, x); - case 16: - return bigint_comba_sqr16(z, x); - case 24: - return bigint_comba_sqr24(z, x); - default: - return basecase_sqr(z, 2*N, x, N); - } - } - - const size_t N2 = N / 2; - - const word* x0 = x; - const word* x1 = x + N2; - word* z0 = z; - word* z1 = z + N; - - word* ws0 = workspace; - word* ws1 = workspace + N; - - clear_mem(workspace, 2*N); - - // See comment in karatsuba_mul - bigint_sub_abs(z0, x0, x1, N2, workspace); - karatsuba_sqr(ws0, z0, N2, ws1); - - karatsuba_sqr(z0, x0, N2, ws1); - karatsuba_sqr(z1, x1, N2, ws1); - - const word ws_carry = bigint_add3_nc(ws1, z0, N, z1, N); - word z_carry = bigint_add2_nc(z + N2, N, ws1, N); - - z_carry += bigint_add2_nc(z + N + N2, N2, &ws_carry, 1); - bigint_add2_nc(z + N + N2, N2, &z_carry, 1); - - /* - * This is only actually required if cmp (result of bigint_sub_abs) is != 0, - * however if cmp==0 then ws0[0:N] == 0 and avoiding the jump hides a - * timing channel. - */ - bigint_sub2(z + N2, 2*N-N2, ws0, N); - } - -/* -* Pick a good size for the Karatsuba multiply -*/ -size_t karatsuba_size(size_t z_size, - size_t x_size, size_t x_sw, - size_t y_size, size_t y_sw) - { - if(x_sw > x_size || x_sw > y_size || y_sw > x_size || y_sw > y_size) - return 0; - - if(((x_size == x_sw) && (x_size % 2)) || - ((y_size == y_sw) && (y_size % 2))) - return 0; - - const size_t start = (x_sw > y_sw) ? x_sw : y_sw; - const size_t end = (x_size < y_size) ? x_size : y_size; - - if(start == end) - { - if(start % 2) - return 0; - return start; - } - - for(size_t j = start; j <= end; ++j) - { - if(j % 2) - continue; - - if(2*j > z_size) - return 0; - - if(x_sw <= j && j <= x_size && y_sw <= j && j <= y_size) - { - if(j % 4 == 2 && - (j+2) <= x_size && (j+2) <= y_size && 2*(j+2) <= z_size) - return j+2; - return j; - } - } - - return 0; - } - -/* -* Pick a good size for the Karatsuba squaring -*/ -size_t karatsuba_size(size_t z_size, size_t x_size, size_t x_sw) - { - if(x_sw == x_size) - { - if(x_sw % 2) - return 0; - return x_sw; - } - - for(size_t j = x_sw; j <= x_size; ++j) - { - if(j % 2) - continue; - - if(2*j > z_size) - return 0; - - if(j % 4 == 2 && (j+2) <= x_size && 2*(j+2) <= z_size) - return j+2; - return j; - } - - return 0; - } - -template -inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, - size_t y_sw, size_t y_size, - size_t z_size) - { - return (x_sw <= SZ && x_size >= SZ && - y_sw <= SZ && y_size >= SZ && - z_size >= 2*SZ); - } - -template -inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, - size_t z_size) - { - return (x_sw <= SZ && x_size >= SZ && z_size >= 2*SZ); - } + for (size_t j = x_size_8; j != x_size; ++j) + z[i + j] = word_madd3(x[j], y_i, z[i + j], &carry); + z[x_size + i] = carry; + } } -void bigint_mul(word z[], size_t z_size, - const word x[], size_t x_size, size_t x_sw, - const word y[], size_t y_size, size_t y_sw, - word workspace[], size_t ws_size) - { - clear_mem(z, z_size); +void basecase_sqr(word z[], size_t z_size, const word x[], size_t x_size) { + if (z_size < 2 * x_size) throw Invalid_Argument("basecase_sqr z_size too small"); - if(x_sw == 1) - { - bigint_linmul3(z, y, y_sw, x[0]); - } - else if(y_sw == 1) - { - bigint_linmul3(z, x, x_sw, y[0]); - } - else if(sized_for_comba_mul<4>(x_sw, x_size, y_sw, y_size, z_size)) - { - bigint_comba_mul4(z, x, y); - } - else if(sized_for_comba_mul<6>(x_sw, x_size, y_sw, y_size, z_size)) - { - bigint_comba_mul6(z, x, y); - } - else if(sized_for_comba_mul<8>(x_sw, x_size, y_sw, y_size, z_size)) - { - bigint_comba_mul8(z, x, y); - } - else if(sized_for_comba_mul<9>(x_sw, x_size, y_sw, y_size, z_size)) - { - bigint_comba_mul9(z, x, y); - } - else if(sized_for_comba_mul<16>(x_sw, x_size, y_sw, y_size, z_size)) - { - bigint_comba_mul16(z, x, y); - } - else if(sized_for_comba_mul<24>(x_sw, x_size, y_sw, y_size, z_size)) - { - bigint_comba_mul24(z, x, y); - } - else if(x_sw < KARATSUBA_MULTIPLY_THRESHOLD || - y_sw < KARATSUBA_MULTIPLY_THRESHOLD || - !workspace) - { - basecase_mul(z, z_size, x, x_sw, y, y_sw); - } - else - { - const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw); + const size_t x_size_8 = x_size - (x_size % 8); - if(N && z_size >= 2*N && ws_size >= 2*N) - karatsuba_mul(z, x, y, N, workspace); - else - basecase_mul(z, z_size, x, x_sw, y, y_sw); - } - } + clear_mem(z, z_size); -/* -* Squaring Algorithm Dispatcher -*/ -void bigint_sqr(word z[], size_t z_size, - const word x[], size_t x_size, size_t x_sw, - word workspace[], size_t ws_size) - { - clear_mem(z, z_size); + for (size_t i = 0; i != x_size; ++i) { + const word x_i = x[i]; - BOTAN_ASSERT(z_size/2 >= x_sw, "Output size is sufficient"); + word carry = 0; - if(x_sw == 1) - { - bigint_linmul3(z, x, x_sw, x[0]); - } - else if(sized_for_comba_sqr<4>(x_sw, x_size, z_size)) - { - bigint_comba_sqr4(z, x); - } - else if(sized_for_comba_sqr<6>(x_sw, x_size, z_size)) - { - bigint_comba_sqr6(z, x); - } - else if(sized_for_comba_sqr<8>(x_sw, x_size, z_size)) - { - bigint_comba_sqr8(z, x); - } - else if(sized_for_comba_sqr<9>(x_sw, x_size, z_size)) - { - bigint_comba_sqr9(z, x); - } - else if(sized_for_comba_sqr<16>(x_sw, x_size, z_size)) - { - bigint_comba_sqr16(z, x); - } - else if(sized_for_comba_sqr<24>(x_sw, x_size, z_size)) - { - bigint_comba_sqr24(z, x); - } - else if(x_size < KARATSUBA_SQUARE_THRESHOLD || !workspace) - { - basecase_sqr(z, z_size, x, x_sw); - } - else - { - const size_t N = karatsuba_size(z_size, x_size, x_sw); + for (size_t j = 0; j != x_size_8; j += 8) carry = word8_madd3(z + i + j, x + j, x_i, carry); - if(N && z_size >= 2*N && ws_size >= 2*N) - karatsuba_sqr(z, x, N, workspace); - else - basecase_sqr(z, z_size, x, x_sw); - } - } + for (size_t j = x_size_8; j != x_size; ++j) + z[i + j] = word_madd3(x[j], x_i, z[i + j], &carry); + z[x_size + i] = carry; + } } -/* -* Montgomery Reduction -* (C) 1999-2011 Jack Lloyd -* 2006 Luca Piccarreta -* 2016 Matthias Gierlings -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Karatsuba Multiplication Operation + */ +void karatsuba_mul(word z[], const word x[], const word y[], size_t N, word workspace[]) { + if (N < KARATSUBA_MULTIPLY_THRESHOLD || N % 2) { + switch (N) { + case 6: + return bigint_comba_mul6(z, x, y); + case 8: + return bigint_comba_mul8(z, x, y); + case 9: + return bigint_comba_mul9(z, x, y); + case 16: + return bigint_comba_mul16(z, x, y); + case 24: + return bigint_comba_mul24(z, x, y); + default: + return basecase_mul(z, 2 * N, x, N, y, N); + } + } + + const size_t N2 = N / 2; + + const word* x0 = x; + const word* x1 = x + N2; + const word* y0 = y; + const word* y1 = y + N2; + word* z0 = z; + word* z1 = z + N; + + word* ws0 = workspace; + word* ws1 = workspace + N; + + clear_mem(workspace, 2 * N); + + /* + * If either of cmp0 or cmp1 is zero then z0 or z1 resp is zero here, + * resulting in a no-op - z0*z1 will be equal to zero so we don't need to do + * anything, clear_mem above already set the correct result. + * + * However we ignore the result of the comparisons and always perform the + * subtractions and recursively multiply to avoid the timing channel. + */ + + // First compute (X_lo - X_hi)*(Y_hi - Y_lo) + const auto cmp0 = bigint_sub_abs(z0, x0, x1, N2, workspace); + const auto cmp1 = bigint_sub_abs(z1, y1, y0, N2, workspace); + const auto neg_mask = ~(cmp0 ^ cmp1); + + karatsuba_mul(ws0, z0, z1, N2, ws1); + + // Compute X_lo * Y_lo + karatsuba_mul(z0, x0, y0, N2, ws1); + + // Compute X_hi * Y_hi + karatsuba_mul(z1, x1, y1, N2, ws1); + + const word ws_carry = bigint_add3_nc(ws1, z0, N, z1, N); + word z_carry = bigint_add2_nc(z + N2, N, ws1, N); + + z_carry += bigint_add2_nc(z + N + N2, N2, &ws_carry, 1); + bigint_add2_nc(z + N + N2, N2, &z_carry, 1); + + clear_mem(workspace + N, N2); + + bigint_cnd_add_or_sub(neg_mask, z + N2, workspace, 2 * N - N2); +} + +/* + * Karatsuba Squaring Operation + */ +void karatsuba_sqr(word z[], const word x[], size_t N, word workspace[]) { + if (N < KARATSUBA_SQUARE_THRESHOLD || N % 2) { + switch (N) { + case 6: + return bigint_comba_sqr6(z, x); + case 8: + return bigint_comba_sqr8(z, x); + case 9: + return bigint_comba_sqr9(z, x); + case 16: + return bigint_comba_sqr16(z, x); + case 24: + return bigint_comba_sqr24(z, x); + default: + return basecase_sqr(z, 2 * N, x, N); + } + } + + const size_t N2 = N / 2; + + const word* x0 = x; + const word* x1 = x + N2; + word* z0 = z; + word* z1 = z + N; + + word* ws0 = workspace; + word* ws1 = workspace + N; + + clear_mem(workspace, 2 * N); + + // See comment in karatsuba_mul + bigint_sub_abs(z0, x0, x1, N2, workspace); + karatsuba_sqr(ws0, z0, N2, ws1); + + karatsuba_sqr(z0, x0, N2, ws1); + karatsuba_sqr(z1, x1, N2, ws1); + + const word ws_carry = bigint_add3_nc(ws1, z0, N, z1, N); + word z_carry = bigint_add2_nc(z + N2, N, ws1, N); + + z_carry += bigint_add2_nc(z + N + N2, N2, &ws_carry, 1); + bigint_add2_nc(z + N + N2, N2, &z_carry, 1); + + /* + * This is only actually required if cmp (result of bigint_sub_abs) is != 0, + * however if cmp==0 then ws0[0:N] == 0 and avoiding the jump hides a + * timing channel. + */ + bigint_sub2(z + N2, 2 * N - N2, ws0, N); +} + +/* + * Pick a good size for the Karatsuba multiply + */ +size_t karatsuba_size(size_t z_size, size_t x_size, size_t x_sw, size_t y_size, size_t y_sw) { + if (x_sw > x_size || x_sw > y_size || y_sw > x_size || y_sw > y_size) return 0; + + if (((x_size == x_sw) && (x_size % 2)) || ((y_size == y_sw) && (y_size % 2))) return 0; + + const size_t start = (x_sw > y_sw) ? x_sw : y_sw; + const size_t end = (x_size < y_size) ? x_size : y_size; + + if (start == end) { + if (start % 2) return 0; + return start; + } + + for (size_t j = start; j <= end; ++j) { + if (j % 2) continue; + + if (2 * j > z_size) return 0; + + if (x_sw <= j && j <= x_size && y_sw <= j && j <= y_size) { + if (j % 4 == 2 && (j + 2) <= x_size && (j + 2) <= y_size && 2 * (j + 2) <= z_size) + return j + 2; + return j; + } + } + + return 0; +} + +/* + * Pick a good size for the Karatsuba squaring + */ +size_t karatsuba_size(size_t z_size, size_t x_size, size_t x_sw) { + if (x_sw == x_size) { + if (x_sw % 2) return 0; + return x_sw; + } + + for (size_t j = x_sw; j <= x_size; ++j) { + if (j % 2) continue; + + if (2 * j > z_size) return 0; + + if (j % 4 == 2 && (j + 2) <= x_size && 2 * (j + 2) <= z_size) return j + 2; + return j; + } + + return 0; +} + +template +inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, size_t y_sw, size_t y_size, + size_t z_size) { + return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ); +} + +template +inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, size_t z_size) { + return (x_sw <= SZ && x_size >= SZ && z_size >= 2 * SZ); +} + +} // namespace + +void bigint_mul(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, const word y[], + size_t y_size, size_t y_sw, word workspace[], size_t ws_size) { + clear_mem(z, z_size); + + if (x_sw == 1) { + bigint_linmul3(z, y, y_sw, x[0]); + } else if (y_sw == 1) { + bigint_linmul3(z, x, x_sw, y[0]); + } else if (sized_for_comba_mul<4>(x_sw, x_size, y_sw, y_size, z_size)) { + bigint_comba_mul4(z, x, y); + } else if (sized_for_comba_mul<6>(x_sw, x_size, y_sw, y_size, z_size)) { + bigint_comba_mul6(z, x, y); + } else if (sized_for_comba_mul<8>(x_sw, x_size, y_sw, y_size, z_size)) { + bigint_comba_mul8(z, x, y); + } else if (sized_for_comba_mul<9>(x_sw, x_size, y_sw, y_size, z_size)) { + bigint_comba_mul9(z, x, y); + } else if (sized_for_comba_mul<16>(x_sw, x_size, y_sw, y_size, z_size)) { + bigint_comba_mul16(z, x, y); + } else if (sized_for_comba_mul<24>(x_sw, x_size, y_sw, y_size, z_size)) { + bigint_comba_mul24(z, x, y); + } else if (x_sw < KARATSUBA_MULTIPLY_THRESHOLD || y_sw < KARATSUBA_MULTIPLY_THRESHOLD || + !workspace) { + basecase_mul(z, z_size, x, x_sw, y, y_sw); + } else { + const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw); + + if (N && z_size >= 2 * N && ws_size >= 2 * N) + karatsuba_mul(z, x, y, N, workspace); + else + basecase_mul(z, z_size, x, x_sw, y, y_sw); + } +} + +/* + * Squaring Algorithm Dispatcher + */ +void bigint_sqr(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, + word workspace[], size_t ws_size) { + clear_mem(z, z_size); + + BOTAN_ASSERT(z_size / 2 >= x_sw, "Output size is sufficient"); + + if (x_sw == 1) { + bigint_linmul3(z, x, x_sw, x[0]); + } else if (sized_for_comba_sqr<4>(x_sw, x_size, z_size)) { + bigint_comba_sqr4(z, x); + } else if (sized_for_comba_sqr<6>(x_sw, x_size, z_size)) { + bigint_comba_sqr6(z, x); + } else if (sized_for_comba_sqr<8>(x_sw, x_size, z_size)) { + bigint_comba_sqr8(z, x); + } else if (sized_for_comba_sqr<9>(x_sw, x_size, z_size)) { + bigint_comba_sqr9(z, x); + } else if (sized_for_comba_sqr<16>(x_sw, x_size, z_size)) { + bigint_comba_sqr16(z, x); + } else if (sized_for_comba_sqr<24>(x_sw, x_size, z_size)) { + bigint_comba_sqr24(z, x); + } else if (x_size < KARATSUBA_SQUARE_THRESHOLD || !workspace) { + basecase_sqr(z, z_size, x, x_sw); + } else { + const size_t N = karatsuba_size(z_size, x_size, x_sw); + + if (N && z_size >= 2 * N && ws_size >= 2 * N) + karatsuba_sqr(z, x, N, workspace); + else + basecase_sqr(z, z_size, x, x_sw); + } +} + +} // namespace Botan +/* + * Montgomery Reduction + * (C) 1999-2011 Jack Lloyd + * 2006 Luca Piccarreta + * 2016 Matthias Gierlings + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { /* -* Montgomery reduction - product scanning form -* -* https://www.iacr.org/archive/ches2005/006.pdf -* https://eprint.iacr.org/2013/882.pdf -* https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf -*/ -void bigint_monty_redc_generic(word z[], size_t z_size, - const word p[], size_t p_size, word p_dash, - word ws[]) - { - word w2 = 0, w1 = 0, w0 = 0; + * Montgomery reduction - product scanning form + * + * https://www.iacr.org/archive/ches2005/006.pdf + * https://eprint.iacr.org/2013/882.pdf + * https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf + */ +void bigint_monty_redc_generic(word z[], size_t z_size, const word p[], size_t p_size, word p_dash, + word ws[]) { + word w2 = 0, w1 = 0, w0 = 0; - w0 = z[0]; + w0 = z[0]; - ws[0] = w0 * p_dash; + ws[0] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); - w0 = w1; - w1 = w2; - w2 = 0; + w0 = w1; + w1 = w2; + w2 = 0; - for(size_t i = 1; i != p_size; ++i) - { - for(size_t j = 0; j < i; ++j) - { - word3_muladd(&w2, &w1, &w0, ws[j], p[i-j]); - } + for (size_t i = 1; i != p_size; ++i) { + for (size_t j = 0; j < i; ++j) { + word3_muladd(&w2, &w1, &w0, ws[j], p[i - j]); + } - word3_add(&w2, &w1, &w0, z[i]); + word3_add(&w2, &w1, &w0, z[i]); - ws[i] = w0 * p_dash; + ws[i] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[i], p[0]); + word3_muladd(&w2, &w1, &w0, ws[i], p[0]); - w0 = w1; - w1 = w2; - w2 = 0; - } + w0 = w1; + w1 = w2; + w2 = 0; + } - for(size_t i = 0; i != p_size; ++i) - { - for(size_t j = i + 1; j != p_size; ++j) - { - word3_muladd(&w2, &w1, &w0, ws[j], p[p_size + i-j]); - } + for (size_t i = 0; i != p_size; ++i) { + for (size_t j = i + 1; j != p_size; ++j) { + word3_muladd(&w2, &w1, &w0, ws[j], p[p_size + i - j]); + } - word3_add(&w2, &w1, &w0, z[p_size+i]); + word3_add(&w2, &w1, &w0, z[p_size + i]); - ws[i] = w0; - w0 = w1; - w1 = w2; - w2 = 0; - } + ws[i] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + } - word3_add(&w2, &w1, &w0, z[z_size-1]); + word3_add(&w2, &w1, &w0, z[z_size - 1]); - ws[p_size] = w0; - ws[p_size+1] = w1; + ws[p_size] = w0; + ws[p_size + 1] = w1; - /* - * The result might need to be reduced mod p. To avoid a timing - * channel, always perform the subtraction. If in the compution - * of x - p a borrow is required then x was already < p. - * - * x starts at ws[0] and is p_size+1 bytes long. - * x - p starts at ws[p_size+1] and is also p_size+1 bytes log - * - * Select which address to copy from indexing off of the final - * borrow. - */ + /* + * The result might need to be reduced mod p. To avoid a timing + * channel, always perform the subtraction. If in the compution + * of x - p a borrow is required then x was already < p. + * + * x starts at ws[0] and is p_size+1 bytes long. + * x - p starts at ws[p_size+1] and is also p_size+1 bytes log + * + * Select which address to copy from indexing off of the final + * borrow. + */ - // word borrow = bigint_sub3(ws + p_size + 1, ws, p_size + 1, p, p_size); - word borrow = 0; - for(size_t i = 0; i != p_size; ++i) - ws[p_size + 1 + i] = word_sub(ws[i], p[i], &borrow); - ws[2*p_size+1] = word_sub(ws[p_size], 0, &borrow); + // word borrow = bigint_sub3(ws + p_size + 1, ws, p_size + 1, p, p_size); + word borrow = 0; + for (size_t i = 0; i != p_size; ++i) ws[p_size + 1 + i] = word_sub(ws[i], p[i], &borrow); + ws[2 * p_size + 1] = word_sub(ws[p_size], 0, &borrow); - BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - - CT::conditional_copy_mem(borrow, z, ws, ws + (p_size + 1), (p_size + 1)); - clear_mem(z + p_size, z_size - p_size - 2); - } + BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); + CT::conditional_copy_mem(borrow, z, ws, ws + (p_size + 1), (p_size + 1)); + clear_mem(z + p_size, z_size - p_size - 2); } -void bigint_monty_redc(word z[], - const word p[], size_t p_size, word p_dash, - word ws[], size_t ws_size) - { - const size_t z_size = 2*(p_size+1); +} // namespace - BOTAN_ARG_CHECK(ws_size >= z_size, "workspace too small"); +void bigint_monty_redc(word z[], const word p[], size_t p_size, word p_dash, word ws[], + size_t ws_size) { + const size_t z_size = 2 * (p_size + 1); - if(p_size == 4) - bigint_monty_redc_4(z, p, p_dash, ws); - else if(p_size == 6) - bigint_monty_redc_6(z, p, p_dash, ws); - else if(p_size == 8) - bigint_monty_redc_8(z, p, p_dash, ws); - else if(p_size == 16) - bigint_monty_redc_16(z, p, p_dash, ws); - else if(p_size == 24) - bigint_monty_redc_24(z, p, p_dash, ws); - else if(p_size == 32) - bigint_monty_redc_32(z, p, p_dash, ws); - else - bigint_monty_redc_generic(z, z_size, p, p_size, p_dash, ws); - } + BOTAN_ARG_CHECK(ws_size >= z_size, "workspace too small"); + if (p_size == 4) + bigint_monty_redc_4(z, p, p_dash, ws); + else if (p_size == 6) + bigint_monty_redc_6(z, p, p_dash, ws); + else if (p_size == 8) + bigint_monty_redc_8(z, p, p_dash, ws); + else if (p_size == 16) + bigint_monty_redc_16(z, p, p_dash, ws); + else if (p_size == 24) + bigint_monty_redc_24(z, p, p_dash, ws); + else if (p_size == 32) + bigint_monty_redc_32(z, p, p_dash, ws); + else + bigint_monty_redc_generic(z, z_size, p, p_size, p_dash, ws); } + +} // namespace Botan /* -* This file was automatically generated by ./src/scripts/monty.py on 2018-06-11 -* All manual changes will be lost. Edit the script instead. -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * This file was automatically generated by ./src/scripts/monty.py on 2018-06-11 + * All manual changes will be lost. Edit the script instead. + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -void bigint_monty_redc_4(word z[], const word p[4], word p_dash, word ws[]) - { - word w2 = 0, w1 = 0, w0 = 0; - w0 = z[0]; - ws[0] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[0], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[1]); - word3_add(&w2, &w1, &w0, z[1]); - ws[1] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[1], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[2]); - word3_muladd(&w2, &w1, &w0, ws[1], p[1]); - word3_add(&w2, &w1, &w0, z[2]); - ws[2] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[2], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[3]); - word3_muladd(&w2, &w1, &w0, ws[1], p[2]); - word3_muladd(&w2, &w1, &w0, ws[2], p[1]); - word3_add(&w2, &w1, &w0, z[3]); - ws[3] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[3], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[1], p[3]); - word3_muladd(&w2, &w1, &w0, ws[2], p[2]); - word3_muladd(&w2, &w1, &w0, ws[3], p[1]); - word3_add(&w2, &w1, &w0, z[4]); - ws[0] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[2], p[3]); - word3_muladd(&w2, &w1, &w0, ws[3], p[2]); - word3_add(&w2, &w1, &w0, z[5]); - ws[1] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[3], p[3]); - word3_add(&w2, &w1, &w0, z[6]); - ws[2] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[7]); - ws[3] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[9]); - ws[4] = w0; - ws[5] = w1; - word borrow = 0; - ws[5] = word_sub(ws[0], p[0], &borrow); - ws[6] = word_sub(ws[1], p[1], &borrow); - ws[7] = word_sub(ws[2], p[2], &borrow); - ws[8] = word_sub(ws[3], p[3], &borrow); - ws[9] = word_sub(ws[4], 0, &borrow); - CT::conditional_copy_mem(borrow, z, ws, ws + 5, 5); - clear_mem(z + 4, 2*(4+1) - 4); - } - -void bigint_monty_redc_6(word z[], const word p[6], word p_dash, word ws[]) - { - word w2 = 0, w1 = 0, w0 = 0; - w0 = z[0]; - ws[0] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[0], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[1]); - word3_add(&w2, &w1, &w0, z[1]); - ws[1] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[1], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[2]); - word3_muladd(&w2, &w1, &w0, ws[1], p[1]); - word3_add(&w2, &w1, &w0, z[2]); - ws[2] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[2], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[3]); - word3_muladd(&w2, &w1, &w0, ws[1], p[2]); - word3_muladd(&w2, &w1, &w0, ws[2], p[1]); - word3_add(&w2, &w1, &w0, z[3]); - ws[3] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[3], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[4]); - word3_muladd(&w2, &w1, &w0, ws[1], p[3]); - word3_muladd(&w2, &w1, &w0, ws[2], p[2]); - word3_muladd(&w2, &w1, &w0, ws[3], p[1]); - word3_add(&w2, &w1, &w0, z[4]); - ws[4] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[4], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[5]); - word3_muladd(&w2, &w1, &w0, ws[1], p[4]); - word3_muladd(&w2, &w1, &w0, ws[2], p[3]); - word3_muladd(&w2, &w1, &w0, ws[3], p[2]); - word3_muladd(&w2, &w1, &w0, ws[4], p[1]); - word3_add(&w2, &w1, &w0, z[5]); - ws[5] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[5], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[1], p[5]); - word3_muladd(&w2, &w1, &w0, ws[2], p[4]); - word3_muladd(&w2, &w1, &w0, ws[3], p[3]); - word3_muladd(&w2, &w1, &w0, ws[4], p[2]); - word3_muladd(&w2, &w1, &w0, ws[5], p[1]); - word3_add(&w2, &w1, &w0, z[6]); - ws[0] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[2], p[5]); - word3_muladd(&w2, &w1, &w0, ws[3], p[4]); - word3_muladd(&w2, &w1, &w0, ws[4], p[3]); - word3_muladd(&w2, &w1, &w0, ws[5], p[2]); - word3_add(&w2, &w1, &w0, z[7]); - ws[1] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[3], p[5]); - word3_muladd(&w2, &w1, &w0, ws[4], p[4]); - word3_muladd(&w2, &w1, &w0, ws[5], p[3]); - word3_add(&w2, &w1, &w0, z[8]); - ws[2] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[4], p[5]); - word3_muladd(&w2, &w1, &w0, ws[5], p[4]); - word3_add(&w2, &w1, &w0, z[9]); - ws[3] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[5], p[5]); - word3_add(&w2, &w1, &w0, z[10]); - ws[4] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[11]); - ws[5] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[13]); - ws[6] = w0; - ws[7] = w1; - word borrow = 0; - ws[7] = word_sub(ws[0], p[0], &borrow); - ws[8] = word_sub(ws[1], p[1], &borrow); - ws[9] = word_sub(ws[2], p[2], &borrow); - ws[10] = word_sub(ws[3], p[3], &borrow); - ws[11] = word_sub(ws[4], p[4], &borrow); - ws[12] = word_sub(ws[5], p[5], &borrow); - ws[13] = word_sub(ws[6], 0, &borrow); - CT::conditional_copy_mem(borrow, z, ws, ws + 7, 7); - clear_mem(z + 6, 2*(6+1) - 6); - } - -void bigint_monty_redc_8(word z[], const word p[8], word p_dash, word ws[]) - { - word w2 = 0, w1 = 0, w0 = 0; - w0 = z[0]; - ws[0] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[0], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[1]); - word3_add(&w2, &w1, &w0, z[1]); - ws[1] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[1], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[2]); - word3_muladd(&w2, &w1, &w0, ws[1], p[1]); - word3_add(&w2, &w1, &w0, z[2]); - ws[2] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[2], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[3]); - word3_muladd(&w2, &w1, &w0, ws[1], p[2]); - word3_muladd(&w2, &w1, &w0, ws[2], p[1]); - word3_add(&w2, &w1, &w0, z[3]); - ws[3] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[3], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[4]); - word3_muladd(&w2, &w1, &w0, ws[1], p[3]); - word3_muladd(&w2, &w1, &w0, ws[2], p[2]); - word3_muladd(&w2, &w1, &w0, ws[3], p[1]); - word3_add(&w2, &w1, &w0, z[4]); - ws[4] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[4], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[5]); - word3_muladd(&w2, &w1, &w0, ws[1], p[4]); - word3_muladd(&w2, &w1, &w0, ws[2], p[3]); - word3_muladd(&w2, &w1, &w0, ws[3], p[2]); - word3_muladd(&w2, &w1, &w0, ws[4], p[1]); - word3_add(&w2, &w1, &w0, z[5]); - ws[5] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[5], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[6]); - word3_muladd(&w2, &w1, &w0, ws[1], p[5]); - word3_muladd(&w2, &w1, &w0, ws[2], p[4]); - word3_muladd(&w2, &w1, &w0, ws[3], p[3]); - word3_muladd(&w2, &w1, &w0, ws[4], p[2]); - word3_muladd(&w2, &w1, &w0, ws[5], p[1]); - word3_add(&w2, &w1, &w0, z[6]); - ws[6] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[6], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[7]); - word3_muladd(&w2, &w1, &w0, ws[1], p[6]); - word3_muladd(&w2, &w1, &w0, ws[2], p[5]); - word3_muladd(&w2, &w1, &w0, ws[3], p[4]); - word3_muladd(&w2, &w1, &w0, ws[4], p[3]); - word3_muladd(&w2, &w1, &w0, ws[5], p[2]); - word3_muladd(&w2, &w1, &w0, ws[6], p[1]); - word3_add(&w2, &w1, &w0, z[7]); - ws[7] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[7], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[1], p[7]); - word3_muladd(&w2, &w1, &w0, ws[2], p[6]); - word3_muladd(&w2, &w1, &w0, ws[3], p[5]); - word3_muladd(&w2, &w1, &w0, ws[4], p[4]); - word3_muladd(&w2, &w1, &w0, ws[5], p[3]); - word3_muladd(&w2, &w1, &w0, ws[6], p[2]); - word3_muladd(&w2, &w1, &w0, ws[7], p[1]); - word3_add(&w2, &w1, &w0, z[8]); - ws[0] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[2], p[7]); - word3_muladd(&w2, &w1, &w0, ws[3], p[6]); - word3_muladd(&w2, &w1, &w0, ws[4], p[5]); - word3_muladd(&w2, &w1, &w0, ws[5], p[4]); - word3_muladd(&w2, &w1, &w0, ws[6], p[3]); - word3_muladd(&w2, &w1, &w0, ws[7], p[2]); - word3_add(&w2, &w1, &w0, z[9]); - ws[1] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[3], p[7]); - word3_muladd(&w2, &w1, &w0, ws[4], p[6]); - word3_muladd(&w2, &w1, &w0, ws[5], p[5]); - word3_muladd(&w2, &w1, &w0, ws[6], p[4]); - word3_muladd(&w2, &w1, &w0, ws[7], p[3]); - word3_add(&w2, &w1, &w0, z[10]); - ws[2] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[4], p[7]); - word3_muladd(&w2, &w1, &w0, ws[5], p[6]); - word3_muladd(&w2, &w1, &w0, ws[6], p[5]); - word3_muladd(&w2, &w1, &w0, ws[7], p[4]); - word3_add(&w2, &w1, &w0, z[11]); - ws[3] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[5], p[7]); - word3_muladd(&w2, &w1, &w0, ws[6], p[6]); - word3_muladd(&w2, &w1, &w0, ws[7], p[5]); - word3_add(&w2, &w1, &w0, z[12]); - ws[4] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[6], p[7]); - word3_muladd(&w2, &w1, &w0, ws[7], p[6]); - word3_add(&w2, &w1, &w0, z[13]); - ws[5] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[7], p[7]); - word3_add(&w2, &w1, &w0, z[14]); - ws[6] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[15]); - ws[7] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[17]); - ws[8] = w0; - ws[9] = w1; - word borrow = 0; - ws[9] = word_sub(ws[0], p[0], &borrow); - ws[10] = word_sub(ws[1], p[1], &borrow); - ws[11] = word_sub(ws[2], p[2], &borrow); - ws[12] = word_sub(ws[3], p[3], &borrow); - ws[13] = word_sub(ws[4], p[4], &borrow); - ws[14] = word_sub(ws[5], p[5], &borrow); - ws[15] = word_sub(ws[6], p[6], &borrow); - ws[16] = word_sub(ws[7], p[7], &borrow); - ws[17] = word_sub(ws[8], 0, &borrow); - CT::conditional_copy_mem(borrow, z, ws, ws + 9, 9); - clear_mem(z + 8, 2*(8+1) - 8); - } - -void bigint_monty_redc_16(word z[], const word p[16], word p_dash, word ws[]) - { - word w2 = 0, w1 = 0, w0 = 0; - w0 = z[0]; - ws[0] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[0], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[1]); - word3_add(&w2, &w1, &w0, z[1]); - ws[1] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[1], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[2]); - word3_muladd(&w2, &w1, &w0, ws[1], p[1]); - word3_add(&w2, &w1, &w0, z[2]); - ws[2] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[2], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[3]); - word3_muladd(&w2, &w1, &w0, ws[1], p[2]); - word3_muladd(&w2, &w1, &w0, ws[2], p[1]); - word3_add(&w2, &w1, &w0, z[3]); - ws[3] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[3], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[4]); - word3_muladd(&w2, &w1, &w0, ws[1], p[3]); - word3_muladd(&w2, &w1, &w0, ws[2], p[2]); - word3_muladd(&w2, &w1, &w0, ws[3], p[1]); - word3_add(&w2, &w1, &w0, z[4]); - ws[4] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[4], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[5]); - word3_muladd(&w2, &w1, &w0, ws[1], p[4]); - word3_muladd(&w2, &w1, &w0, ws[2], p[3]); - word3_muladd(&w2, &w1, &w0, ws[3], p[2]); - word3_muladd(&w2, &w1, &w0, ws[4], p[1]); - word3_add(&w2, &w1, &w0, z[5]); - ws[5] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[5], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[6]); - word3_muladd(&w2, &w1, &w0, ws[1], p[5]); - word3_muladd(&w2, &w1, &w0, ws[2], p[4]); - word3_muladd(&w2, &w1, &w0, ws[3], p[3]); - word3_muladd(&w2, &w1, &w0, ws[4], p[2]); - word3_muladd(&w2, &w1, &w0, ws[5], p[1]); - word3_add(&w2, &w1, &w0, z[6]); - ws[6] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[6], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[7]); - word3_muladd(&w2, &w1, &w0, ws[1], p[6]); - word3_muladd(&w2, &w1, &w0, ws[2], p[5]); - word3_muladd(&w2, &w1, &w0, ws[3], p[4]); - word3_muladd(&w2, &w1, &w0, ws[4], p[3]); - word3_muladd(&w2, &w1, &w0, ws[5], p[2]); - word3_muladd(&w2, &w1, &w0, ws[6], p[1]); - word3_add(&w2, &w1, &w0, z[7]); - ws[7] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[7], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[8]); - word3_muladd(&w2, &w1, &w0, ws[1], p[7]); - word3_muladd(&w2, &w1, &w0, ws[2], p[6]); - word3_muladd(&w2, &w1, &w0, ws[3], p[5]); - word3_muladd(&w2, &w1, &w0, ws[4], p[4]); - word3_muladd(&w2, &w1, &w0, ws[5], p[3]); - word3_muladd(&w2, &w1, &w0, ws[6], p[2]); - word3_muladd(&w2, &w1, &w0, ws[7], p[1]); - word3_add(&w2, &w1, &w0, z[8]); - ws[8] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[8], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[9]); - word3_muladd(&w2, &w1, &w0, ws[1], p[8]); - word3_muladd(&w2, &w1, &w0, ws[2], p[7]); - word3_muladd(&w2, &w1, &w0, ws[3], p[6]); - word3_muladd(&w2, &w1, &w0, ws[4], p[5]); - word3_muladd(&w2, &w1, &w0, ws[5], p[4]); - word3_muladd(&w2, &w1, &w0, ws[6], p[3]); - word3_muladd(&w2, &w1, &w0, ws[7], p[2]); - word3_muladd(&w2, &w1, &w0, ws[8], p[1]); - word3_add(&w2, &w1, &w0, z[9]); - ws[9] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[9], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[10]); - word3_muladd(&w2, &w1, &w0, ws[1], p[9]); - word3_muladd(&w2, &w1, &w0, ws[2], p[8]); - word3_muladd(&w2, &w1, &w0, ws[3], p[7]); - word3_muladd(&w2, &w1, &w0, ws[4], p[6]); - word3_muladd(&w2, &w1, &w0, ws[5], p[5]); - word3_muladd(&w2, &w1, &w0, ws[6], p[4]); - word3_muladd(&w2, &w1, &w0, ws[7], p[3]); - word3_muladd(&w2, &w1, &w0, ws[8], p[2]); - word3_muladd(&w2, &w1, &w0, ws[9], p[1]); - word3_add(&w2, &w1, &w0, z[10]); - ws[10] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[10], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[11]); - word3_muladd(&w2, &w1, &w0, ws[1], p[10]); - word3_muladd(&w2, &w1, &w0, ws[2], p[9]); - word3_muladd(&w2, &w1, &w0, ws[3], p[8]); - word3_muladd(&w2, &w1, &w0, ws[4], p[7]); - word3_muladd(&w2, &w1, &w0, ws[5], p[6]); - word3_muladd(&w2, &w1, &w0, ws[6], p[5]); - word3_muladd(&w2, &w1, &w0, ws[7], p[4]); - word3_muladd(&w2, &w1, &w0, ws[8], p[3]); - word3_muladd(&w2, &w1, &w0, ws[9], p[2]); - word3_muladd(&w2, &w1, &w0, ws[10], p[1]); - word3_add(&w2, &w1, &w0, z[11]); - ws[11] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[11], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[12]); - word3_muladd(&w2, &w1, &w0, ws[1], p[11]); - word3_muladd(&w2, &w1, &w0, ws[2], p[10]); - word3_muladd(&w2, &w1, &w0, ws[3], p[9]); - word3_muladd(&w2, &w1, &w0, ws[4], p[8]); - word3_muladd(&w2, &w1, &w0, ws[5], p[7]); - word3_muladd(&w2, &w1, &w0, ws[6], p[6]); - word3_muladd(&w2, &w1, &w0, ws[7], p[5]); - word3_muladd(&w2, &w1, &w0, ws[8], p[4]); - word3_muladd(&w2, &w1, &w0, ws[9], p[3]); - word3_muladd(&w2, &w1, &w0, ws[10], p[2]); - word3_muladd(&w2, &w1, &w0, ws[11], p[1]); - word3_add(&w2, &w1, &w0, z[12]); - ws[12] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[12], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[13]); - word3_muladd(&w2, &w1, &w0, ws[1], p[12]); - word3_muladd(&w2, &w1, &w0, ws[2], p[11]); - word3_muladd(&w2, &w1, &w0, ws[3], p[10]); - word3_muladd(&w2, &w1, &w0, ws[4], p[9]); - word3_muladd(&w2, &w1, &w0, ws[5], p[8]); - word3_muladd(&w2, &w1, &w0, ws[6], p[7]); - word3_muladd(&w2, &w1, &w0, ws[7], p[6]); - word3_muladd(&w2, &w1, &w0, ws[8], p[5]); - word3_muladd(&w2, &w1, &w0, ws[9], p[4]); - word3_muladd(&w2, &w1, &w0, ws[10], p[3]); - word3_muladd(&w2, &w1, &w0, ws[11], p[2]); - word3_muladd(&w2, &w1, &w0, ws[12], p[1]); - word3_add(&w2, &w1, &w0, z[13]); - ws[13] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[13], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[14]); - word3_muladd(&w2, &w1, &w0, ws[1], p[13]); - word3_muladd(&w2, &w1, &w0, ws[2], p[12]); - word3_muladd(&w2, &w1, &w0, ws[3], p[11]); - word3_muladd(&w2, &w1, &w0, ws[4], p[10]); - word3_muladd(&w2, &w1, &w0, ws[5], p[9]); - word3_muladd(&w2, &w1, &w0, ws[6], p[8]); - word3_muladd(&w2, &w1, &w0, ws[7], p[7]); - word3_muladd(&w2, &w1, &w0, ws[8], p[6]); - word3_muladd(&w2, &w1, &w0, ws[9], p[5]); - word3_muladd(&w2, &w1, &w0, ws[10], p[4]); - word3_muladd(&w2, &w1, &w0, ws[11], p[3]); - word3_muladd(&w2, &w1, &w0, ws[12], p[2]); - word3_muladd(&w2, &w1, &w0, ws[13], p[1]); - word3_add(&w2, &w1, &w0, z[14]); - ws[14] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[14], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[15]); - word3_muladd(&w2, &w1, &w0, ws[1], p[14]); - word3_muladd(&w2, &w1, &w0, ws[2], p[13]); - word3_muladd(&w2, &w1, &w0, ws[3], p[12]); - word3_muladd(&w2, &w1, &w0, ws[4], p[11]); - word3_muladd(&w2, &w1, &w0, ws[5], p[10]); - word3_muladd(&w2, &w1, &w0, ws[6], p[9]); - word3_muladd(&w2, &w1, &w0, ws[7], p[8]); - word3_muladd(&w2, &w1, &w0, ws[8], p[7]); - word3_muladd(&w2, &w1, &w0, ws[9], p[6]); - word3_muladd(&w2, &w1, &w0, ws[10], p[5]); - word3_muladd(&w2, &w1, &w0, ws[11], p[4]); - word3_muladd(&w2, &w1, &w0, ws[12], p[3]); - word3_muladd(&w2, &w1, &w0, ws[13], p[2]); - word3_muladd(&w2, &w1, &w0, ws[14], p[1]); - word3_add(&w2, &w1, &w0, z[15]); - ws[15] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[15], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[1], p[15]); - word3_muladd(&w2, &w1, &w0, ws[2], p[14]); - word3_muladd(&w2, &w1, &w0, ws[3], p[13]); - word3_muladd(&w2, &w1, &w0, ws[4], p[12]); - word3_muladd(&w2, &w1, &w0, ws[5], p[11]); - word3_muladd(&w2, &w1, &w0, ws[6], p[10]); - word3_muladd(&w2, &w1, &w0, ws[7], p[9]); - word3_muladd(&w2, &w1, &w0, ws[8], p[8]); - word3_muladd(&w2, &w1, &w0, ws[9], p[7]); - word3_muladd(&w2, &w1, &w0, ws[10], p[6]); - word3_muladd(&w2, &w1, &w0, ws[11], p[5]); - word3_muladd(&w2, &w1, &w0, ws[12], p[4]); - word3_muladd(&w2, &w1, &w0, ws[13], p[3]); - word3_muladd(&w2, &w1, &w0, ws[14], p[2]); - word3_muladd(&w2, &w1, &w0, ws[15], p[1]); - word3_add(&w2, &w1, &w0, z[16]); - ws[0] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[2], p[15]); - word3_muladd(&w2, &w1, &w0, ws[3], p[14]); - word3_muladd(&w2, &w1, &w0, ws[4], p[13]); - word3_muladd(&w2, &w1, &w0, ws[5], p[12]); - word3_muladd(&w2, &w1, &w0, ws[6], p[11]); - word3_muladd(&w2, &w1, &w0, ws[7], p[10]); - word3_muladd(&w2, &w1, &w0, ws[8], p[9]); - word3_muladd(&w2, &w1, &w0, ws[9], p[8]); - word3_muladd(&w2, &w1, &w0, ws[10], p[7]); - word3_muladd(&w2, &w1, &w0, ws[11], p[6]); - word3_muladd(&w2, &w1, &w0, ws[12], p[5]); - word3_muladd(&w2, &w1, &w0, ws[13], p[4]); - word3_muladd(&w2, &w1, &w0, ws[14], p[3]); - word3_muladd(&w2, &w1, &w0, ws[15], p[2]); - word3_add(&w2, &w1, &w0, z[17]); - ws[1] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[3], p[15]); - word3_muladd(&w2, &w1, &w0, ws[4], p[14]); - word3_muladd(&w2, &w1, &w0, ws[5], p[13]); - word3_muladd(&w2, &w1, &w0, ws[6], p[12]); - word3_muladd(&w2, &w1, &w0, ws[7], p[11]); - word3_muladd(&w2, &w1, &w0, ws[8], p[10]); - word3_muladd(&w2, &w1, &w0, ws[9], p[9]); - word3_muladd(&w2, &w1, &w0, ws[10], p[8]); - word3_muladd(&w2, &w1, &w0, ws[11], p[7]); - word3_muladd(&w2, &w1, &w0, ws[12], p[6]); - word3_muladd(&w2, &w1, &w0, ws[13], p[5]); - word3_muladd(&w2, &w1, &w0, ws[14], p[4]); - word3_muladd(&w2, &w1, &w0, ws[15], p[3]); - word3_add(&w2, &w1, &w0, z[18]); - ws[2] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[4], p[15]); - word3_muladd(&w2, &w1, &w0, ws[5], p[14]); - word3_muladd(&w2, &w1, &w0, ws[6], p[13]); - word3_muladd(&w2, &w1, &w0, ws[7], p[12]); - word3_muladd(&w2, &w1, &w0, ws[8], p[11]); - word3_muladd(&w2, &w1, &w0, ws[9], p[10]); - word3_muladd(&w2, &w1, &w0, ws[10], p[9]); - word3_muladd(&w2, &w1, &w0, ws[11], p[8]); - word3_muladd(&w2, &w1, &w0, ws[12], p[7]); - word3_muladd(&w2, &w1, &w0, ws[13], p[6]); - word3_muladd(&w2, &w1, &w0, ws[14], p[5]); - word3_muladd(&w2, &w1, &w0, ws[15], p[4]); - word3_add(&w2, &w1, &w0, z[19]); - ws[3] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[5], p[15]); - word3_muladd(&w2, &w1, &w0, ws[6], p[14]); - word3_muladd(&w2, &w1, &w0, ws[7], p[13]); - word3_muladd(&w2, &w1, &w0, ws[8], p[12]); - word3_muladd(&w2, &w1, &w0, ws[9], p[11]); - word3_muladd(&w2, &w1, &w0, ws[10], p[10]); - word3_muladd(&w2, &w1, &w0, ws[11], p[9]); - word3_muladd(&w2, &w1, &w0, ws[12], p[8]); - word3_muladd(&w2, &w1, &w0, ws[13], p[7]); - word3_muladd(&w2, &w1, &w0, ws[14], p[6]); - word3_muladd(&w2, &w1, &w0, ws[15], p[5]); - word3_add(&w2, &w1, &w0, z[20]); - ws[4] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[6], p[15]); - word3_muladd(&w2, &w1, &w0, ws[7], p[14]); - word3_muladd(&w2, &w1, &w0, ws[8], p[13]); - word3_muladd(&w2, &w1, &w0, ws[9], p[12]); - word3_muladd(&w2, &w1, &w0, ws[10], p[11]); - word3_muladd(&w2, &w1, &w0, ws[11], p[10]); - word3_muladd(&w2, &w1, &w0, ws[12], p[9]); - word3_muladd(&w2, &w1, &w0, ws[13], p[8]); - word3_muladd(&w2, &w1, &w0, ws[14], p[7]); - word3_muladd(&w2, &w1, &w0, ws[15], p[6]); - word3_add(&w2, &w1, &w0, z[21]); - ws[5] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[7], p[15]); - word3_muladd(&w2, &w1, &w0, ws[8], p[14]); - word3_muladd(&w2, &w1, &w0, ws[9], p[13]); - word3_muladd(&w2, &w1, &w0, ws[10], p[12]); - word3_muladd(&w2, &w1, &w0, ws[11], p[11]); - word3_muladd(&w2, &w1, &w0, ws[12], p[10]); - word3_muladd(&w2, &w1, &w0, ws[13], p[9]); - word3_muladd(&w2, &w1, &w0, ws[14], p[8]); - word3_muladd(&w2, &w1, &w0, ws[15], p[7]); - word3_add(&w2, &w1, &w0, z[22]); - ws[6] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[8], p[15]); - word3_muladd(&w2, &w1, &w0, ws[9], p[14]); - word3_muladd(&w2, &w1, &w0, ws[10], p[13]); - word3_muladd(&w2, &w1, &w0, ws[11], p[12]); - word3_muladd(&w2, &w1, &w0, ws[12], p[11]); - word3_muladd(&w2, &w1, &w0, ws[13], p[10]); - word3_muladd(&w2, &w1, &w0, ws[14], p[9]); - word3_muladd(&w2, &w1, &w0, ws[15], p[8]); - word3_add(&w2, &w1, &w0, z[23]); - ws[7] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[9], p[15]); - word3_muladd(&w2, &w1, &w0, ws[10], p[14]); - word3_muladd(&w2, &w1, &w0, ws[11], p[13]); - word3_muladd(&w2, &w1, &w0, ws[12], p[12]); - word3_muladd(&w2, &w1, &w0, ws[13], p[11]); - word3_muladd(&w2, &w1, &w0, ws[14], p[10]); - word3_muladd(&w2, &w1, &w0, ws[15], p[9]); - word3_add(&w2, &w1, &w0, z[24]); - ws[8] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[10], p[15]); - word3_muladd(&w2, &w1, &w0, ws[11], p[14]); - word3_muladd(&w2, &w1, &w0, ws[12], p[13]); - word3_muladd(&w2, &w1, &w0, ws[13], p[12]); - word3_muladd(&w2, &w1, &w0, ws[14], p[11]); - word3_muladd(&w2, &w1, &w0, ws[15], p[10]); - word3_add(&w2, &w1, &w0, z[25]); - ws[9] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[11], p[15]); - word3_muladd(&w2, &w1, &w0, ws[12], p[14]); - word3_muladd(&w2, &w1, &w0, ws[13], p[13]); - word3_muladd(&w2, &w1, &w0, ws[14], p[12]); - word3_muladd(&w2, &w1, &w0, ws[15], p[11]); - word3_add(&w2, &w1, &w0, z[26]); - ws[10] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[12], p[15]); - word3_muladd(&w2, &w1, &w0, ws[13], p[14]); - word3_muladd(&w2, &w1, &w0, ws[14], p[13]); - word3_muladd(&w2, &w1, &w0, ws[15], p[12]); - word3_add(&w2, &w1, &w0, z[27]); - ws[11] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[13], p[15]); - word3_muladd(&w2, &w1, &w0, ws[14], p[14]); - word3_muladd(&w2, &w1, &w0, ws[15], p[13]); - word3_add(&w2, &w1, &w0, z[28]); - ws[12] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[14], p[15]); - word3_muladd(&w2, &w1, &w0, ws[15], p[14]); - word3_add(&w2, &w1, &w0, z[29]); - ws[13] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[15], p[15]); - word3_add(&w2, &w1, &w0, z[30]); - ws[14] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[31]); - ws[15] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[33]); - ws[16] = w0; - ws[17] = w1; - word borrow = bigint_sub3(ws + 16 + 1, ws, 16 + 1, p, 16); - CT::conditional_copy_mem(borrow, z, ws, ws + 17, 17); - clear_mem(z + 16, 2*(16+1) - 16); - } - -void bigint_monty_redc_24(word z[], const word p[24], word p_dash, word ws[]) - { - word w2 = 0, w1 = 0, w0 = 0; - w0 = z[0]; - ws[0] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[0], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[1]); - word3_add(&w2, &w1, &w0, z[1]); - ws[1] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[1], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[2]); - word3_muladd(&w2, &w1, &w0, ws[1], p[1]); - word3_add(&w2, &w1, &w0, z[2]); - ws[2] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[2], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[3]); - word3_muladd(&w2, &w1, &w0, ws[1], p[2]); - word3_muladd(&w2, &w1, &w0, ws[2], p[1]); - word3_add(&w2, &w1, &w0, z[3]); - ws[3] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[3], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[4]); - word3_muladd(&w2, &w1, &w0, ws[1], p[3]); - word3_muladd(&w2, &w1, &w0, ws[2], p[2]); - word3_muladd(&w2, &w1, &w0, ws[3], p[1]); - word3_add(&w2, &w1, &w0, z[4]); - ws[4] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[4], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[5]); - word3_muladd(&w2, &w1, &w0, ws[1], p[4]); - word3_muladd(&w2, &w1, &w0, ws[2], p[3]); - word3_muladd(&w2, &w1, &w0, ws[3], p[2]); - word3_muladd(&w2, &w1, &w0, ws[4], p[1]); - word3_add(&w2, &w1, &w0, z[5]); - ws[5] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[5], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[6]); - word3_muladd(&w2, &w1, &w0, ws[1], p[5]); - word3_muladd(&w2, &w1, &w0, ws[2], p[4]); - word3_muladd(&w2, &w1, &w0, ws[3], p[3]); - word3_muladd(&w2, &w1, &w0, ws[4], p[2]); - word3_muladd(&w2, &w1, &w0, ws[5], p[1]); - word3_add(&w2, &w1, &w0, z[6]); - ws[6] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[6], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[7]); - word3_muladd(&w2, &w1, &w0, ws[1], p[6]); - word3_muladd(&w2, &w1, &w0, ws[2], p[5]); - word3_muladd(&w2, &w1, &w0, ws[3], p[4]); - word3_muladd(&w2, &w1, &w0, ws[4], p[3]); - word3_muladd(&w2, &w1, &w0, ws[5], p[2]); - word3_muladd(&w2, &w1, &w0, ws[6], p[1]); - word3_add(&w2, &w1, &w0, z[7]); - ws[7] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[7], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[8]); - word3_muladd(&w2, &w1, &w0, ws[1], p[7]); - word3_muladd(&w2, &w1, &w0, ws[2], p[6]); - word3_muladd(&w2, &w1, &w0, ws[3], p[5]); - word3_muladd(&w2, &w1, &w0, ws[4], p[4]); - word3_muladd(&w2, &w1, &w0, ws[5], p[3]); - word3_muladd(&w2, &w1, &w0, ws[6], p[2]); - word3_muladd(&w2, &w1, &w0, ws[7], p[1]); - word3_add(&w2, &w1, &w0, z[8]); - ws[8] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[8], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[9]); - word3_muladd(&w2, &w1, &w0, ws[1], p[8]); - word3_muladd(&w2, &w1, &w0, ws[2], p[7]); - word3_muladd(&w2, &w1, &w0, ws[3], p[6]); - word3_muladd(&w2, &w1, &w0, ws[4], p[5]); - word3_muladd(&w2, &w1, &w0, ws[5], p[4]); - word3_muladd(&w2, &w1, &w0, ws[6], p[3]); - word3_muladd(&w2, &w1, &w0, ws[7], p[2]); - word3_muladd(&w2, &w1, &w0, ws[8], p[1]); - word3_add(&w2, &w1, &w0, z[9]); - ws[9] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[9], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[10]); - word3_muladd(&w2, &w1, &w0, ws[1], p[9]); - word3_muladd(&w2, &w1, &w0, ws[2], p[8]); - word3_muladd(&w2, &w1, &w0, ws[3], p[7]); - word3_muladd(&w2, &w1, &w0, ws[4], p[6]); - word3_muladd(&w2, &w1, &w0, ws[5], p[5]); - word3_muladd(&w2, &w1, &w0, ws[6], p[4]); - word3_muladd(&w2, &w1, &w0, ws[7], p[3]); - word3_muladd(&w2, &w1, &w0, ws[8], p[2]); - word3_muladd(&w2, &w1, &w0, ws[9], p[1]); - word3_add(&w2, &w1, &w0, z[10]); - ws[10] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[10], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[11]); - word3_muladd(&w2, &w1, &w0, ws[1], p[10]); - word3_muladd(&w2, &w1, &w0, ws[2], p[9]); - word3_muladd(&w2, &w1, &w0, ws[3], p[8]); - word3_muladd(&w2, &w1, &w0, ws[4], p[7]); - word3_muladd(&w2, &w1, &w0, ws[5], p[6]); - word3_muladd(&w2, &w1, &w0, ws[6], p[5]); - word3_muladd(&w2, &w1, &w0, ws[7], p[4]); - word3_muladd(&w2, &w1, &w0, ws[8], p[3]); - word3_muladd(&w2, &w1, &w0, ws[9], p[2]); - word3_muladd(&w2, &w1, &w0, ws[10], p[1]); - word3_add(&w2, &w1, &w0, z[11]); - ws[11] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[11], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[12]); - word3_muladd(&w2, &w1, &w0, ws[1], p[11]); - word3_muladd(&w2, &w1, &w0, ws[2], p[10]); - word3_muladd(&w2, &w1, &w0, ws[3], p[9]); - word3_muladd(&w2, &w1, &w0, ws[4], p[8]); - word3_muladd(&w2, &w1, &w0, ws[5], p[7]); - word3_muladd(&w2, &w1, &w0, ws[6], p[6]); - word3_muladd(&w2, &w1, &w0, ws[7], p[5]); - word3_muladd(&w2, &w1, &w0, ws[8], p[4]); - word3_muladd(&w2, &w1, &w0, ws[9], p[3]); - word3_muladd(&w2, &w1, &w0, ws[10], p[2]); - word3_muladd(&w2, &w1, &w0, ws[11], p[1]); - word3_add(&w2, &w1, &w0, z[12]); - ws[12] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[12], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[13]); - word3_muladd(&w2, &w1, &w0, ws[1], p[12]); - word3_muladd(&w2, &w1, &w0, ws[2], p[11]); - word3_muladd(&w2, &w1, &w0, ws[3], p[10]); - word3_muladd(&w2, &w1, &w0, ws[4], p[9]); - word3_muladd(&w2, &w1, &w0, ws[5], p[8]); - word3_muladd(&w2, &w1, &w0, ws[6], p[7]); - word3_muladd(&w2, &w1, &w0, ws[7], p[6]); - word3_muladd(&w2, &w1, &w0, ws[8], p[5]); - word3_muladd(&w2, &w1, &w0, ws[9], p[4]); - word3_muladd(&w2, &w1, &w0, ws[10], p[3]); - word3_muladd(&w2, &w1, &w0, ws[11], p[2]); - word3_muladd(&w2, &w1, &w0, ws[12], p[1]); - word3_add(&w2, &w1, &w0, z[13]); - ws[13] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[13], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[14]); - word3_muladd(&w2, &w1, &w0, ws[1], p[13]); - word3_muladd(&w2, &w1, &w0, ws[2], p[12]); - word3_muladd(&w2, &w1, &w0, ws[3], p[11]); - word3_muladd(&w2, &w1, &w0, ws[4], p[10]); - word3_muladd(&w2, &w1, &w0, ws[5], p[9]); - word3_muladd(&w2, &w1, &w0, ws[6], p[8]); - word3_muladd(&w2, &w1, &w0, ws[7], p[7]); - word3_muladd(&w2, &w1, &w0, ws[8], p[6]); - word3_muladd(&w2, &w1, &w0, ws[9], p[5]); - word3_muladd(&w2, &w1, &w0, ws[10], p[4]); - word3_muladd(&w2, &w1, &w0, ws[11], p[3]); - word3_muladd(&w2, &w1, &w0, ws[12], p[2]); - word3_muladd(&w2, &w1, &w0, ws[13], p[1]); - word3_add(&w2, &w1, &w0, z[14]); - ws[14] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[14], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[15]); - word3_muladd(&w2, &w1, &w0, ws[1], p[14]); - word3_muladd(&w2, &w1, &w0, ws[2], p[13]); - word3_muladd(&w2, &w1, &w0, ws[3], p[12]); - word3_muladd(&w2, &w1, &w0, ws[4], p[11]); - word3_muladd(&w2, &w1, &w0, ws[5], p[10]); - word3_muladd(&w2, &w1, &w0, ws[6], p[9]); - word3_muladd(&w2, &w1, &w0, ws[7], p[8]); - word3_muladd(&w2, &w1, &w0, ws[8], p[7]); - word3_muladd(&w2, &w1, &w0, ws[9], p[6]); - word3_muladd(&w2, &w1, &w0, ws[10], p[5]); - word3_muladd(&w2, &w1, &w0, ws[11], p[4]); - word3_muladd(&w2, &w1, &w0, ws[12], p[3]); - word3_muladd(&w2, &w1, &w0, ws[13], p[2]); - word3_muladd(&w2, &w1, &w0, ws[14], p[1]); - word3_add(&w2, &w1, &w0, z[15]); - ws[15] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[15], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[16]); - word3_muladd(&w2, &w1, &w0, ws[1], p[15]); - word3_muladd(&w2, &w1, &w0, ws[2], p[14]); - word3_muladd(&w2, &w1, &w0, ws[3], p[13]); - word3_muladd(&w2, &w1, &w0, ws[4], p[12]); - word3_muladd(&w2, &w1, &w0, ws[5], p[11]); - word3_muladd(&w2, &w1, &w0, ws[6], p[10]); - word3_muladd(&w2, &w1, &w0, ws[7], p[9]); - word3_muladd(&w2, &w1, &w0, ws[8], p[8]); - word3_muladd(&w2, &w1, &w0, ws[9], p[7]); - word3_muladd(&w2, &w1, &w0, ws[10], p[6]); - word3_muladd(&w2, &w1, &w0, ws[11], p[5]); - word3_muladd(&w2, &w1, &w0, ws[12], p[4]); - word3_muladd(&w2, &w1, &w0, ws[13], p[3]); - word3_muladd(&w2, &w1, &w0, ws[14], p[2]); - word3_muladd(&w2, &w1, &w0, ws[15], p[1]); - word3_add(&w2, &w1, &w0, z[16]); - ws[16] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[16], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[17]); - word3_muladd(&w2, &w1, &w0, ws[1], p[16]); - word3_muladd(&w2, &w1, &w0, ws[2], p[15]); - word3_muladd(&w2, &w1, &w0, ws[3], p[14]); - word3_muladd(&w2, &w1, &w0, ws[4], p[13]); - word3_muladd(&w2, &w1, &w0, ws[5], p[12]); - word3_muladd(&w2, &w1, &w0, ws[6], p[11]); - word3_muladd(&w2, &w1, &w0, ws[7], p[10]); - word3_muladd(&w2, &w1, &w0, ws[8], p[9]); - word3_muladd(&w2, &w1, &w0, ws[9], p[8]); - word3_muladd(&w2, &w1, &w0, ws[10], p[7]); - word3_muladd(&w2, &w1, &w0, ws[11], p[6]); - word3_muladd(&w2, &w1, &w0, ws[12], p[5]); - word3_muladd(&w2, &w1, &w0, ws[13], p[4]); - word3_muladd(&w2, &w1, &w0, ws[14], p[3]); - word3_muladd(&w2, &w1, &w0, ws[15], p[2]); - word3_muladd(&w2, &w1, &w0, ws[16], p[1]); - word3_add(&w2, &w1, &w0, z[17]); - ws[17] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[17], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[18]); - word3_muladd(&w2, &w1, &w0, ws[1], p[17]); - word3_muladd(&w2, &w1, &w0, ws[2], p[16]); - word3_muladd(&w2, &w1, &w0, ws[3], p[15]); - word3_muladd(&w2, &w1, &w0, ws[4], p[14]); - word3_muladd(&w2, &w1, &w0, ws[5], p[13]); - word3_muladd(&w2, &w1, &w0, ws[6], p[12]); - word3_muladd(&w2, &w1, &w0, ws[7], p[11]); - word3_muladd(&w2, &w1, &w0, ws[8], p[10]); - word3_muladd(&w2, &w1, &w0, ws[9], p[9]); - word3_muladd(&w2, &w1, &w0, ws[10], p[8]); - word3_muladd(&w2, &w1, &w0, ws[11], p[7]); - word3_muladd(&w2, &w1, &w0, ws[12], p[6]); - word3_muladd(&w2, &w1, &w0, ws[13], p[5]); - word3_muladd(&w2, &w1, &w0, ws[14], p[4]); - word3_muladd(&w2, &w1, &w0, ws[15], p[3]); - word3_muladd(&w2, &w1, &w0, ws[16], p[2]); - word3_muladd(&w2, &w1, &w0, ws[17], p[1]); - word3_add(&w2, &w1, &w0, z[18]); - ws[18] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[18], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[19]); - word3_muladd(&w2, &w1, &w0, ws[1], p[18]); - word3_muladd(&w2, &w1, &w0, ws[2], p[17]); - word3_muladd(&w2, &w1, &w0, ws[3], p[16]); - word3_muladd(&w2, &w1, &w0, ws[4], p[15]); - word3_muladd(&w2, &w1, &w0, ws[5], p[14]); - word3_muladd(&w2, &w1, &w0, ws[6], p[13]); - word3_muladd(&w2, &w1, &w0, ws[7], p[12]); - word3_muladd(&w2, &w1, &w0, ws[8], p[11]); - word3_muladd(&w2, &w1, &w0, ws[9], p[10]); - word3_muladd(&w2, &w1, &w0, ws[10], p[9]); - word3_muladd(&w2, &w1, &w0, ws[11], p[8]); - word3_muladd(&w2, &w1, &w0, ws[12], p[7]); - word3_muladd(&w2, &w1, &w0, ws[13], p[6]); - word3_muladd(&w2, &w1, &w0, ws[14], p[5]); - word3_muladd(&w2, &w1, &w0, ws[15], p[4]); - word3_muladd(&w2, &w1, &w0, ws[16], p[3]); - word3_muladd(&w2, &w1, &w0, ws[17], p[2]); - word3_muladd(&w2, &w1, &w0, ws[18], p[1]); - word3_add(&w2, &w1, &w0, z[19]); - ws[19] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[19], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[20]); - word3_muladd(&w2, &w1, &w0, ws[1], p[19]); - word3_muladd(&w2, &w1, &w0, ws[2], p[18]); - word3_muladd(&w2, &w1, &w0, ws[3], p[17]); - word3_muladd(&w2, &w1, &w0, ws[4], p[16]); - word3_muladd(&w2, &w1, &w0, ws[5], p[15]); - word3_muladd(&w2, &w1, &w0, ws[6], p[14]); - word3_muladd(&w2, &w1, &w0, ws[7], p[13]); - word3_muladd(&w2, &w1, &w0, ws[8], p[12]); - word3_muladd(&w2, &w1, &w0, ws[9], p[11]); - word3_muladd(&w2, &w1, &w0, ws[10], p[10]); - word3_muladd(&w2, &w1, &w0, ws[11], p[9]); - word3_muladd(&w2, &w1, &w0, ws[12], p[8]); - word3_muladd(&w2, &w1, &w0, ws[13], p[7]); - word3_muladd(&w2, &w1, &w0, ws[14], p[6]); - word3_muladd(&w2, &w1, &w0, ws[15], p[5]); - word3_muladd(&w2, &w1, &w0, ws[16], p[4]); - word3_muladd(&w2, &w1, &w0, ws[17], p[3]); - word3_muladd(&w2, &w1, &w0, ws[18], p[2]); - word3_muladd(&w2, &w1, &w0, ws[19], p[1]); - word3_add(&w2, &w1, &w0, z[20]); - ws[20] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[20], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[21]); - word3_muladd(&w2, &w1, &w0, ws[1], p[20]); - word3_muladd(&w2, &w1, &w0, ws[2], p[19]); - word3_muladd(&w2, &w1, &w0, ws[3], p[18]); - word3_muladd(&w2, &w1, &w0, ws[4], p[17]); - word3_muladd(&w2, &w1, &w0, ws[5], p[16]); - word3_muladd(&w2, &w1, &w0, ws[6], p[15]); - word3_muladd(&w2, &w1, &w0, ws[7], p[14]); - word3_muladd(&w2, &w1, &w0, ws[8], p[13]); - word3_muladd(&w2, &w1, &w0, ws[9], p[12]); - word3_muladd(&w2, &w1, &w0, ws[10], p[11]); - word3_muladd(&w2, &w1, &w0, ws[11], p[10]); - word3_muladd(&w2, &w1, &w0, ws[12], p[9]); - word3_muladd(&w2, &w1, &w0, ws[13], p[8]); - word3_muladd(&w2, &w1, &w0, ws[14], p[7]); - word3_muladd(&w2, &w1, &w0, ws[15], p[6]); - word3_muladd(&w2, &w1, &w0, ws[16], p[5]); - word3_muladd(&w2, &w1, &w0, ws[17], p[4]); - word3_muladd(&w2, &w1, &w0, ws[18], p[3]); - word3_muladd(&w2, &w1, &w0, ws[19], p[2]); - word3_muladd(&w2, &w1, &w0, ws[20], p[1]); - word3_add(&w2, &w1, &w0, z[21]); - ws[21] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[21], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[22]); - word3_muladd(&w2, &w1, &w0, ws[1], p[21]); - word3_muladd(&w2, &w1, &w0, ws[2], p[20]); - word3_muladd(&w2, &w1, &w0, ws[3], p[19]); - word3_muladd(&w2, &w1, &w0, ws[4], p[18]); - word3_muladd(&w2, &w1, &w0, ws[5], p[17]); - word3_muladd(&w2, &w1, &w0, ws[6], p[16]); - word3_muladd(&w2, &w1, &w0, ws[7], p[15]); - word3_muladd(&w2, &w1, &w0, ws[8], p[14]); - word3_muladd(&w2, &w1, &w0, ws[9], p[13]); - word3_muladd(&w2, &w1, &w0, ws[10], p[12]); - word3_muladd(&w2, &w1, &w0, ws[11], p[11]); - word3_muladd(&w2, &w1, &w0, ws[12], p[10]); - word3_muladd(&w2, &w1, &w0, ws[13], p[9]); - word3_muladd(&w2, &w1, &w0, ws[14], p[8]); - word3_muladd(&w2, &w1, &w0, ws[15], p[7]); - word3_muladd(&w2, &w1, &w0, ws[16], p[6]); - word3_muladd(&w2, &w1, &w0, ws[17], p[5]); - word3_muladd(&w2, &w1, &w0, ws[18], p[4]); - word3_muladd(&w2, &w1, &w0, ws[19], p[3]); - word3_muladd(&w2, &w1, &w0, ws[20], p[2]); - word3_muladd(&w2, &w1, &w0, ws[21], p[1]); - word3_add(&w2, &w1, &w0, z[22]); - ws[22] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[22], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[23]); - word3_muladd(&w2, &w1, &w0, ws[1], p[22]); - word3_muladd(&w2, &w1, &w0, ws[2], p[21]); - word3_muladd(&w2, &w1, &w0, ws[3], p[20]); - word3_muladd(&w2, &w1, &w0, ws[4], p[19]); - word3_muladd(&w2, &w1, &w0, ws[5], p[18]); - word3_muladd(&w2, &w1, &w0, ws[6], p[17]); - word3_muladd(&w2, &w1, &w0, ws[7], p[16]); - word3_muladd(&w2, &w1, &w0, ws[8], p[15]); - word3_muladd(&w2, &w1, &w0, ws[9], p[14]); - word3_muladd(&w2, &w1, &w0, ws[10], p[13]); - word3_muladd(&w2, &w1, &w0, ws[11], p[12]); - word3_muladd(&w2, &w1, &w0, ws[12], p[11]); - word3_muladd(&w2, &w1, &w0, ws[13], p[10]); - word3_muladd(&w2, &w1, &w0, ws[14], p[9]); - word3_muladd(&w2, &w1, &w0, ws[15], p[8]); - word3_muladd(&w2, &w1, &w0, ws[16], p[7]); - word3_muladd(&w2, &w1, &w0, ws[17], p[6]); - word3_muladd(&w2, &w1, &w0, ws[18], p[5]); - word3_muladd(&w2, &w1, &w0, ws[19], p[4]); - word3_muladd(&w2, &w1, &w0, ws[20], p[3]); - word3_muladd(&w2, &w1, &w0, ws[21], p[2]); - word3_muladd(&w2, &w1, &w0, ws[22], p[1]); - word3_add(&w2, &w1, &w0, z[23]); - ws[23] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[23], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[1], p[23]); - word3_muladd(&w2, &w1, &w0, ws[2], p[22]); - word3_muladd(&w2, &w1, &w0, ws[3], p[21]); - word3_muladd(&w2, &w1, &w0, ws[4], p[20]); - word3_muladd(&w2, &w1, &w0, ws[5], p[19]); - word3_muladd(&w2, &w1, &w0, ws[6], p[18]); - word3_muladd(&w2, &w1, &w0, ws[7], p[17]); - word3_muladd(&w2, &w1, &w0, ws[8], p[16]); - word3_muladd(&w2, &w1, &w0, ws[9], p[15]); - word3_muladd(&w2, &w1, &w0, ws[10], p[14]); - word3_muladd(&w2, &w1, &w0, ws[11], p[13]); - word3_muladd(&w2, &w1, &w0, ws[12], p[12]); - word3_muladd(&w2, &w1, &w0, ws[13], p[11]); - word3_muladd(&w2, &w1, &w0, ws[14], p[10]); - word3_muladd(&w2, &w1, &w0, ws[15], p[9]); - word3_muladd(&w2, &w1, &w0, ws[16], p[8]); - word3_muladd(&w2, &w1, &w0, ws[17], p[7]); - word3_muladd(&w2, &w1, &w0, ws[18], p[6]); - word3_muladd(&w2, &w1, &w0, ws[19], p[5]); - word3_muladd(&w2, &w1, &w0, ws[20], p[4]); - word3_muladd(&w2, &w1, &w0, ws[21], p[3]); - word3_muladd(&w2, &w1, &w0, ws[22], p[2]); - word3_muladd(&w2, &w1, &w0, ws[23], p[1]); - word3_add(&w2, &w1, &w0, z[24]); - ws[0] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[2], p[23]); - word3_muladd(&w2, &w1, &w0, ws[3], p[22]); - word3_muladd(&w2, &w1, &w0, ws[4], p[21]); - word3_muladd(&w2, &w1, &w0, ws[5], p[20]); - word3_muladd(&w2, &w1, &w0, ws[6], p[19]); - word3_muladd(&w2, &w1, &w0, ws[7], p[18]); - word3_muladd(&w2, &w1, &w0, ws[8], p[17]); - word3_muladd(&w2, &w1, &w0, ws[9], p[16]); - word3_muladd(&w2, &w1, &w0, ws[10], p[15]); - word3_muladd(&w2, &w1, &w0, ws[11], p[14]); - word3_muladd(&w2, &w1, &w0, ws[12], p[13]); - word3_muladd(&w2, &w1, &w0, ws[13], p[12]); - word3_muladd(&w2, &w1, &w0, ws[14], p[11]); - word3_muladd(&w2, &w1, &w0, ws[15], p[10]); - word3_muladd(&w2, &w1, &w0, ws[16], p[9]); - word3_muladd(&w2, &w1, &w0, ws[17], p[8]); - word3_muladd(&w2, &w1, &w0, ws[18], p[7]); - word3_muladd(&w2, &w1, &w0, ws[19], p[6]); - word3_muladd(&w2, &w1, &w0, ws[20], p[5]); - word3_muladd(&w2, &w1, &w0, ws[21], p[4]); - word3_muladd(&w2, &w1, &w0, ws[22], p[3]); - word3_muladd(&w2, &w1, &w0, ws[23], p[2]); - word3_add(&w2, &w1, &w0, z[25]); - ws[1] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[3], p[23]); - word3_muladd(&w2, &w1, &w0, ws[4], p[22]); - word3_muladd(&w2, &w1, &w0, ws[5], p[21]); - word3_muladd(&w2, &w1, &w0, ws[6], p[20]); - word3_muladd(&w2, &w1, &w0, ws[7], p[19]); - word3_muladd(&w2, &w1, &w0, ws[8], p[18]); - word3_muladd(&w2, &w1, &w0, ws[9], p[17]); - word3_muladd(&w2, &w1, &w0, ws[10], p[16]); - word3_muladd(&w2, &w1, &w0, ws[11], p[15]); - word3_muladd(&w2, &w1, &w0, ws[12], p[14]); - word3_muladd(&w2, &w1, &w0, ws[13], p[13]); - word3_muladd(&w2, &w1, &w0, ws[14], p[12]); - word3_muladd(&w2, &w1, &w0, ws[15], p[11]); - word3_muladd(&w2, &w1, &w0, ws[16], p[10]); - word3_muladd(&w2, &w1, &w0, ws[17], p[9]); - word3_muladd(&w2, &w1, &w0, ws[18], p[8]); - word3_muladd(&w2, &w1, &w0, ws[19], p[7]); - word3_muladd(&w2, &w1, &w0, ws[20], p[6]); - word3_muladd(&w2, &w1, &w0, ws[21], p[5]); - word3_muladd(&w2, &w1, &w0, ws[22], p[4]); - word3_muladd(&w2, &w1, &w0, ws[23], p[3]); - word3_add(&w2, &w1, &w0, z[26]); - ws[2] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[4], p[23]); - word3_muladd(&w2, &w1, &w0, ws[5], p[22]); - word3_muladd(&w2, &w1, &w0, ws[6], p[21]); - word3_muladd(&w2, &w1, &w0, ws[7], p[20]); - word3_muladd(&w2, &w1, &w0, ws[8], p[19]); - word3_muladd(&w2, &w1, &w0, ws[9], p[18]); - word3_muladd(&w2, &w1, &w0, ws[10], p[17]); - word3_muladd(&w2, &w1, &w0, ws[11], p[16]); - word3_muladd(&w2, &w1, &w0, ws[12], p[15]); - word3_muladd(&w2, &w1, &w0, ws[13], p[14]); - word3_muladd(&w2, &w1, &w0, ws[14], p[13]); - word3_muladd(&w2, &w1, &w0, ws[15], p[12]); - word3_muladd(&w2, &w1, &w0, ws[16], p[11]); - word3_muladd(&w2, &w1, &w0, ws[17], p[10]); - word3_muladd(&w2, &w1, &w0, ws[18], p[9]); - word3_muladd(&w2, &w1, &w0, ws[19], p[8]); - word3_muladd(&w2, &w1, &w0, ws[20], p[7]); - word3_muladd(&w2, &w1, &w0, ws[21], p[6]); - word3_muladd(&w2, &w1, &w0, ws[22], p[5]); - word3_muladd(&w2, &w1, &w0, ws[23], p[4]); - word3_add(&w2, &w1, &w0, z[27]); - ws[3] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[5], p[23]); - word3_muladd(&w2, &w1, &w0, ws[6], p[22]); - word3_muladd(&w2, &w1, &w0, ws[7], p[21]); - word3_muladd(&w2, &w1, &w0, ws[8], p[20]); - word3_muladd(&w2, &w1, &w0, ws[9], p[19]); - word3_muladd(&w2, &w1, &w0, ws[10], p[18]); - word3_muladd(&w2, &w1, &w0, ws[11], p[17]); - word3_muladd(&w2, &w1, &w0, ws[12], p[16]); - word3_muladd(&w2, &w1, &w0, ws[13], p[15]); - word3_muladd(&w2, &w1, &w0, ws[14], p[14]); - word3_muladd(&w2, &w1, &w0, ws[15], p[13]); - word3_muladd(&w2, &w1, &w0, ws[16], p[12]); - word3_muladd(&w2, &w1, &w0, ws[17], p[11]); - word3_muladd(&w2, &w1, &w0, ws[18], p[10]); - word3_muladd(&w2, &w1, &w0, ws[19], p[9]); - word3_muladd(&w2, &w1, &w0, ws[20], p[8]); - word3_muladd(&w2, &w1, &w0, ws[21], p[7]); - word3_muladd(&w2, &w1, &w0, ws[22], p[6]); - word3_muladd(&w2, &w1, &w0, ws[23], p[5]); - word3_add(&w2, &w1, &w0, z[28]); - ws[4] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[6], p[23]); - word3_muladd(&w2, &w1, &w0, ws[7], p[22]); - word3_muladd(&w2, &w1, &w0, ws[8], p[21]); - word3_muladd(&w2, &w1, &w0, ws[9], p[20]); - word3_muladd(&w2, &w1, &w0, ws[10], p[19]); - word3_muladd(&w2, &w1, &w0, ws[11], p[18]); - word3_muladd(&w2, &w1, &w0, ws[12], p[17]); - word3_muladd(&w2, &w1, &w0, ws[13], p[16]); - word3_muladd(&w2, &w1, &w0, ws[14], p[15]); - word3_muladd(&w2, &w1, &w0, ws[15], p[14]); - word3_muladd(&w2, &w1, &w0, ws[16], p[13]); - word3_muladd(&w2, &w1, &w0, ws[17], p[12]); - word3_muladd(&w2, &w1, &w0, ws[18], p[11]); - word3_muladd(&w2, &w1, &w0, ws[19], p[10]); - word3_muladd(&w2, &w1, &w0, ws[20], p[9]); - word3_muladd(&w2, &w1, &w0, ws[21], p[8]); - word3_muladd(&w2, &w1, &w0, ws[22], p[7]); - word3_muladd(&w2, &w1, &w0, ws[23], p[6]); - word3_add(&w2, &w1, &w0, z[29]); - ws[5] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[7], p[23]); - word3_muladd(&w2, &w1, &w0, ws[8], p[22]); - word3_muladd(&w2, &w1, &w0, ws[9], p[21]); - word3_muladd(&w2, &w1, &w0, ws[10], p[20]); - word3_muladd(&w2, &w1, &w0, ws[11], p[19]); - word3_muladd(&w2, &w1, &w0, ws[12], p[18]); - word3_muladd(&w2, &w1, &w0, ws[13], p[17]); - word3_muladd(&w2, &w1, &w0, ws[14], p[16]); - word3_muladd(&w2, &w1, &w0, ws[15], p[15]); - word3_muladd(&w2, &w1, &w0, ws[16], p[14]); - word3_muladd(&w2, &w1, &w0, ws[17], p[13]); - word3_muladd(&w2, &w1, &w0, ws[18], p[12]); - word3_muladd(&w2, &w1, &w0, ws[19], p[11]); - word3_muladd(&w2, &w1, &w0, ws[20], p[10]); - word3_muladd(&w2, &w1, &w0, ws[21], p[9]); - word3_muladd(&w2, &w1, &w0, ws[22], p[8]); - word3_muladd(&w2, &w1, &w0, ws[23], p[7]); - word3_add(&w2, &w1, &w0, z[30]); - ws[6] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[8], p[23]); - word3_muladd(&w2, &w1, &w0, ws[9], p[22]); - word3_muladd(&w2, &w1, &w0, ws[10], p[21]); - word3_muladd(&w2, &w1, &w0, ws[11], p[20]); - word3_muladd(&w2, &w1, &w0, ws[12], p[19]); - word3_muladd(&w2, &w1, &w0, ws[13], p[18]); - word3_muladd(&w2, &w1, &w0, ws[14], p[17]); - word3_muladd(&w2, &w1, &w0, ws[15], p[16]); - word3_muladd(&w2, &w1, &w0, ws[16], p[15]); - word3_muladd(&w2, &w1, &w0, ws[17], p[14]); - word3_muladd(&w2, &w1, &w0, ws[18], p[13]); - word3_muladd(&w2, &w1, &w0, ws[19], p[12]); - word3_muladd(&w2, &w1, &w0, ws[20], p[11]); - word3_muladd(&w2, &w1, &w0, ws[21], p[10]); - word3_muladd(&w2, &w1, &w0, ws[22], p[9]); - word3_muladd(&w2, &w1, &w0, ws[23], p[8]); - word3_add(&w2, &w1, &w0, z[31]); - ws[7] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[9], p[23]); - word3_muladd(&w2, &w1, &w0, ws[10], p[22]); - word3_muladd(&w2, &w1, &w0, ws[11], p[21]); - word3_muladd(&w2, &w1, &w0, ws[12], p[20]); - word3_muladd(&w2, &w1, &w0, ws[13], p[19]); - word3_muladd(&w2, &w1, &w0, ws[14], p[18]); - word3_muladd(&w2, &w1, &w0, ws[15], p[17]); - word3_muladd(&w2, &w1, &w0, ws[16], p[16]); - word3_muladd(&w2, &w1, &w0, ws[17], p[15]); - word3_muladd(&w2, &w1, &w0, ws[18], p[14]); - word3_muladd(&w2, &w1, &w0, ws[19], p[13]); - word3_muladd(&w2, &w1, &w0, ws[20], p[12]); - word3_muladd(&w2, &w1, &w0, ws[21], p[11]); - word3_muladd(&w2, &w1, &w0, ws[22], p[10]); - word3_muladd(&w2, &w1, &w0, ws[23], p[9]); - word3_add(&w2, &w1, &w0, z[32]); - ws[8] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[10], p[23]); - word3_muladd(&w2, &w1, &w0, ws[11], p[22]); - word3_muladd(&w2, &w1, &w0, ws[12], p[21]); - word3_muladd(&w2, &w1, &w0, ws[13], p[20]); - word3_muladd(&w2, &w1, &w0, ws[14], p[19]); - word3_muladd(&w2, &w1, &w0, ws[15], p[18]); - word3_muladd(&w2, &w1, &w0, ws[16], p[17]); - word3_muladd(&w2, &w1, &w0, ws[17], p[16]); - word3_muladd(&w2, &w1, &w0, ws[18], p[15]); - word3_muladd(&w2, &w1, &w0, ws[19], p[14]); - word3_muladd(&w2, &w1, &w0, ws[20], p[13]); - word3_muladd(&w2, &w1, &w0, ws[21], p[12]); - word3_muladd(&w2, &w1, &w0, ws[22], p[11]); - word3_muladd(&w2, &w1, &w0, ws[23], p[10]); - word3_add(&w2, &w1, &w0, z[33]); - ws[9] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[11], p[23]); - word3_muladd(&w2, &w1, &w0, ws[12], p[22]); - word3_muladd(&w2, &w1, &w0, ws[13], p[21]); - word3_muladd(&w2, &w1, &w0, ws[14], p[20]); - word3_muladd(&w2, &w1, &w0, ws[15], p[19]); - word3_muladd(&w2, &w1, &w0, ws[16], p[18]); - word3_muladd(&w2, &w1, &w0, ws[17], p[17]); - word3_muladd(&w2, &w1, &w0, ws[18], p[16]); - word3_muladd(&w2, &w1, &w0, ws[19], p[15]); - word3_muladd(&w2, &w1, &w0, ws[20], p[14]); - word3_muladd(&w2, &w1, &w0, ws[21], p[13]); - word3_muladd(&w2, &w1, &w0, ws[22], p[12]); - word3_muladd(&w2, &w1, &w0, ws[23], p[11]); - word3_add(&w2, &w1, &w0, z[34]); - ws[10] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[12], p[23]); - word3_muladd(&w2, &w1, &w0, ws[13], p[22]); - word3_muladd(&w2, &w1, &w0, ws[14], p[21]); - word3_muladd(&w2, &w1, &w0, ws[15], p[20]); - word3_muladd(&w2, &w1, &w0, ws[16], p[19]); - word3_muladd(&w2, &w1, &w0, ws[17], p[18]); - word3_muladd(&w2, &w1, &w0, ws[18], p[17]); - word3_muladd(&w2, &w1, &w0, ws[19], p[16]); - word3_muladd(&w2, &w1, &w0, ws[20], p[15]); - word3_muladd(&w2, &w1, &w0, ws[21], p[14]); - word3_muladd(&w2, &w1, &w0, ws[22], p[13]); - word3_muladd(&w2, &w1, &w0, ws[23], p[12]); - word3_add(&w2, &w1, &w0, z[35]); - ws[11] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[13], p[23]); - word3_muladd(&w2, &w1, &w0, ws[14], p[22]); - word3_muladd(&w2, &w1, &w0, ws[15], p[21]); - word3_muladd(&w2, &w1, &w0, ws[16], p[20]); - word3_muladd(&w2, &w1, &w0, ws[17], p[19]); - word3_muladd(&w2, &w1, &w0, ws[18], p[18]); - word3_muladd(&w2, &w1, &w0, ws[19], p[17]); - word3_muladd(&w2, &w1, &w0, ws[20], p[16]); - word3_muladd(&w2, &w1, &w0, ws[21], p[15]); - word3_muladd(&w2, &w1, &w0, ws[22], p[14]); - word3_muladd(&w2, &w1, &w0, ws[23], p[13]); - word3_add(&w2, &w1, &w0, z[36]); - ws[12] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[14], p[23]); - word3_muladd(&w2, &w1, &w0, ws[15], p[22]); - word3_muladd(&w2, &w1, &w0, ws[16], p[21]); - word3_muladd(&w2, &w1, &w0, ws[17], p[20]); - word3_muladd(&w2, &w1, &w0, ws[18], p[19]); - word3_muladd(&w2, &w1, &w0, ws[19], p[18]); - word3_muladd(&w2, &w1, &w0, ws[20], p[17]); - word3_muladd(&w2, &w1, &w0, ws[21], p[16]); - word3_muladd(&w2, &w1, &w0, ws[22], p[15]); - word3_muladd(&w2, &w1, &w0, ws[23], p[14]); - word3_add(&w2, &w1, &w0, z[37]); - ws[13] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[15], p[23]); - word3_muladd(&w2, &w1, &w0, ws[16], p[22]); - word3_muladd(&w2, &w1, &w0, ws[17], p[21]); - word3_muladd(&w2, &w1, &w0, ws[18], p[20]); - word3_muladd(&w2, &w1, &w0, ws[19], p[19]); - word3_muladd(&w2, &w1, &w0, ws[20], p[18]); - word3_muladd(&w2, &w1, &w0, ws[21], p[17]); - word3_muladd(&w2, &w1, &w0, ws[22], p[16]); - word3_muladd(&w2, &w1, &w0, ws[23], p[15]); - word3_add(&w2, &w1, &w0, z[38]); - ws[14] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[16], p[23]); - word3_muladd(&w2, &w1, &w0, ws[17], p[22]); - word3_muladd(&w2, &w1, &w0, ws[18], p[21]); - word3_muladd(&w2, &w1, &w0, ws[19], p[20]); - word3_muladd(&w2, &w1, &w0, ws[20], p[19]); - word3_muladd(&w2, &w1, &w0, ws[21], p[18]); - word3_muladd(&w2, &w1, &w0, ws[22], p[17]); - word3_muladd(&w2, &w1, &w0, ws[23], p[16]); - word3_add(&w2, &w1, &w0, z[39]); - ws[15] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[17], p[23]); - word3_muladd(&w2, &w1, &w0, ws[18], p[22]); - word3_muladd(&w2, &w1, &w0, ws[19], p[21]); - word3_muladd(&w2, &w1, &w0, ws[20], p[20]); - word3_muladd(&w2, &w1, &w0, ws[21], p[19]); - word3_muladd(&w2, &w1, &w0, ws[22], p[18]); - word3_muladd(&w2, &w1, &w0, ws[23], p[17]); - word3_add(&w2, &w1, &w0, z[40]); - ws[16] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[18], p[23]); - word3_muladd(&w2, &w1, &w0, ws[19], p[22]); - word3_muladd(&w2, &w1, &w0, ws[20], p[21]); - word3_muladd(&w2, &w1, &w0, ws[21], p[20]); - word3_muladd(&w2, &w1, &w0, ws[22], p[19]); - word3_muladd(&w2, &w1, &w0, ws[23], p[18]); - word3_add(&w2, &w1, &w0, z[41]); - ws[17] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[19], p[23]); - word3_muladd(&w2, &w1, &w0, ws[20], p[22]); - word3_muladd(&w2, &w1, &w0, ws[21], p[21]); - word3_muladd(&w2, &w1, &w0, ws[22], p[20]); - word3_muladd(&w2, &w1, &w0, ws[23], p[19]); - word3_add(&w2, &w1, &w0, z[42]); - ws[18] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[20], p[23]); - word3_muladd(&w2, &w1, &w0, ws[21], p[22]); - word3_muladd(&w2, &w1, &w0, ws[22], p[21]); - word3_muladd(&w2, &w1, &w0, ws[23], p[20]); - word3_add(&w2, &w1, &w0, z[43]); - ws[19] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[21], p[23]); - word3_muladd(&w2, &w1, &w0, ws[22], p[22]); - word3_muladd(&w2, &w1, &w0, ws[23], p[21]); - word3_add(&w2, &w1, &w0, z[44]); - ws[20] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[22], p[23]); - word3_muladd(&w2, &w1, &w0, ws[23], p[22]); - word3_add(&w2, &w1, &w0, z[45]); - ws[21] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[23], p[23]); - word3_add(&w2, &w1, &w0, z[46]); - ws[22] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[47]); - ws[23] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[49]); - ws[24] = w0; - ws[25] = w1; - word borrow = bigint_sub3(ws + 24 + 1, ws, 24 + 1, p, 24); - CT::conditional_copy_mem(borrow, z, ws, ws + 25, 25); - clear_mem(z + 24, 2*(24+1) - 24); - } - -void bigint_monty_redc_32(word z[], const word p[32], word p_dash, word ws[]) - { - word w2 = 0, w1 = 0, w0 = 0; - w0 = z[0]; - ws[0] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[0], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[1]); - word3_add(&w2, &w1, &w0, z[1]); - ws[1] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[1], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[2]); - word3_muladd(&w2, &w1, &w0, ws[1], p[1]); - word3_add(&w2, &w1, &w0, z[2]); - ws[2] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[2], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[3]); - word3_muladd(&w2, &w1, &w0, ws[1], p[2]); - word3_muladd(&w2, &w1, &w0, ws[2], p[1]); - word3_add(&w2, &w1, &w0, z[3]); - ws[3] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[3], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[4]); - word3_muladd(&w2, &w1, &w0, ws[1], p[3]); - word3_muladd(&w2, &w1, &w0, ws[2], p[2]); - word3_muladd(&w2, &w1, &w0, ws[3], p[1]); - word3_add(&w2, &w1, &w0, z[4]); - ws[4] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[4], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[5]); - word3_muladd(&w2, &w1, &w0, ws[1], p[4]); - word3_muladd(&w2, &w1, &w0, ws[2], p[3]); - word3_muladd(&w2, &w1, &w0, ws[3], p[2]); - word3_muladd(&w2, &w1, &w0, ws[4], p[1]); - word3_add(&w2, &w1, &w0, z[5]); - ws[5] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[5], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[6]); - word3_muladd(&w2, &w1, &w0, ws[1], p[5]); - word3_muladd(&w2, &w1, &w0, ws[2], p[4]); - word3_muladd(&w2, &w1, &w0, ws[3], p[3]); - word3_muladd(&w2, &w1, &w0, ws[4], p[2]); - word3_muladd(&w2, &w1, &w0, ws[5], p[1]); - word3_add(&w2, &w1, &w0, z[6]); - ws[6] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[6], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[7]); - word3_muladd(&w2, &w1, &w0, ws[1], p[6]); - word3_muladd(&w2, &w1, &w0, ws[2], p[5]); - word3_muladd(&w2, &w1, &w0, ws[3], p[4]); - word3_muladd(&w2, &w1, &w0, ws[4], p[3]); - word3_muladd(&w2, &w1, &w0, ws[5], p[2]); - word3_muladd(&w2, &w1, &w0, ws[6], p[1]); - word3_add(&w2, &w1, &w0, z[7]); - ws[7] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[7], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[8]); - word3_muladd(&w2, &w1, &w0, ws[1], p[7]); - word3_muladd(&w2, &w1, &w0, ws[2], p[6]); - word3_muladd(&w2, &w1, &w0, ws[3], p[5]); - word3_muladd(&w2, &w1, &w0, ws[4], p[4]); - word3_muladd(&w2, &w1, &w0, ws[5], p[3]); - word3_muladd(&w2, &w1, &w0, ws[6], p[2]); - word3_muladd(&w2, &w1, &w0, ws[7], p[1]); - word3_add(&w2, &w1, &w0, z[8]); - ws[8] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[8], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[9]); - word3_muladd(&w2, &w1, &w0, ws[1], p[8]); - word3_muladd(&w2, &w1, &w0, ws[2], p[7]); - word3_muladd(&w2, &w1, &w0, ws[3], p[6]); - word3_muladd(&w2, &w1, &w0, ws[4], p[5]); - word3_muladd(&w2, &w1, &w0, ws[5], p[4]); - word3_muladd(&w2, &w1, &w0, ws[6], p[3]); - word3_muladd(&w2, &w1, &w0, ws[7], p[2]); - word3_muladd(&w2, &w1, &w0, ws[8], p[1]); - word3_add(&w2, &w1, &w0, z[9]); - ws[9] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[9], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[10]); - word3_muladd(&w2, &w1, &w0, ws[1], p[9]); - word3_muladd(&w2, &w1, &w0, ws[2], p[8]); - word3_muladd(&w2, &w1, &w0, ws[3], p[7]); - word3_muladd(&w2, &w1, &w0, ws[4], p[6]); - word3_muladd(&w2, &w1, &w0, ws[5], p[5]); - word3_muladd(&w2, &w1, &w0, ws[6], p[4]); - word3_muladd(&w2, &w1, &w0, ws[7], p[3]); - word3_muladd(&w2, &w1, &w0, ws[8], p[2]); - word3_muladd(&w2, &w1, &w0, ws[9], p[1]); - word3_add(&w2, &w1, &w0, z[10]); - ws[10] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[10], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[11]); - word3_muladd(&w2, &w1, &w0, ws[1], p[10]); - word3_muladd(&w2, &w1, &w0, ws[2], p[9]); - word3_muladd(&w2, &w1, &w0, ws[3], p[8]); - word3_muladd(&w2, &w1, &w0, ws[4], p[7]); - word3_muladd(&w2, &w1, &w0, ws[5], p[6]); - word3_muladd(&w2, &w1, &w0, ws[6], p[5]); - word3_muladd(&w2, &w1, &w0, ws[7], p[4]); - word3_muladd(&w2, &w1, &w0, ws[8], p[3]); - word3_muladd(&w2, &w1, &w0, ws[9], p[2]); - word3_muladd(&w2, &w1, &w0, ws[10], p[1]); - word3_add(&w2, &w1, &w0, z[11]); - ws[11] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[11], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[12]); - word3_muladd(&w2, &w1, &w0, ws[1], p[11]); - word3_muladd(&w2, &w1, &w0, ws[2], p[10]); - word3_muladd(&w2, &w1, &w0, ws[3], p[9]); - word3_muladd(&w2, &w1, &w0, ws[4], p[8]); - word3_muladd(&w2, &w1, &w0, ws[5], p[7]); - word3_muladd(&w2, &w1, &w0, ws[6], p[6]); - word3_muladd(&w2, &w1, &w0, ws[7], p[5]); - word3_muladd(&w2, &w1, &w0, ws[8], p[4]); - word3_muladd(&w2, &w1, &w0, ws[9], p[3]); - word3_muladd(&w2, &w1, &w0, ws[10], p[2]); - word3_muladd(&w2, &w1, &w0, ws[11], p[1]); - word3_add(&w2, &w1, &w0, z[12]); - ws[12] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[12], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[13]); - word3_muladd(&w2, &w1, &w0, ws[1], p[12]); - word3_muladd(&w2, &w1, &w0, ws[2], p[11]); - word3_muladd(&w2, &w1, &w0, ws[3], p[10]); - word3_muladd(&w2, &w1, &w0, ws[4], p[9]); - word3_muladd(&w2, &w1, &w0, ws[5], p[8]); - word3_muladd(&w2, &w1, &w0, ws[6], p[7]); - word3_muladd(&w2, &w1, &w0, ws[7], p[6]); - word3_muladd(&w2, &w1, &w0, ws[8], p[5]); - word3_muladd(&w2, &w1, &w0, ws[9], p[4]); - word3_muladd(&w2, &w1, &w0, ws[10], p[3]); - word3_muladd(&w2, &w1, &w0, ws[11], p[2]); - word3_muladd(&w2, &w1, &w0, ws[12], p[1]); - word3_add(&w2, &w1, &w0, z[13]); - ws[13] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[13], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[14]); - word3_muladd(&w2, &w1, &w0, ws[1], p[13]); - word3_muladd(&w2, &w1, &w0, ws[2], p[12]); - word3_muladd(&w2, &w1, &w0, ws[3], p[11]); - word3_muladd(&w2, &w1, &w0, ws[4], p[10]); - word3_muladd(&w2, &w1, &w0, ws[5], p[9]); - word3_muladd(&w2, &w1, &w0, ws[6], p[8]); - word3_muladd(&w2, &w1, &w0, ws[7], p[7]); - word3_muladd(&w2, &w1, &w0, ws[8], p[6]); - word3_muladd(&w2, &w1, &w0, ws[9], p[5]); - word3_muladd(&w2, &w1, &w0, ws[10], p[4]); - word3_muladd(&w2, &w1, &w0, ws[11], p[3]); - word3_muladd(&w2, &w1, &w0, ws[12], p[2]); - word3_muladd(&w2, &w1, &w0, ws[13], p[1]); - word3_add(&w2, &w1, &w0, z[14]); - ws[14] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[14], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[15]); - word3_muladd(&w2, &w1, &w0, ws[1], p[14]); - word3_muladd(&w2, &w1, &w0, ws[2], p[13]); - word3_muladd(&w2, &w1, &w0, ws[3], p[12]); - word3_muladd(&w2, &w1, &w0, ws[4], p[11]); - word3_muladd(&w2, &w1, &w0, ws[5], p[10]); - word3_muladd(&w2, &w1, &w0, ws[6], p[9]); - word3_muladd(&w2, &w1, &w0, ws[7], p[8]); - word3_muladd(&w2, &w1, &w0, ws[8], p[7]); - word3_muladd(&w2, &w1, &w0, ws[9], p[6]); - word3_muladd(&w2, &w1, &w0, ws[10], p[5]); - word3_muladd(&w2, &w1, &w0, ws[11], p[4]); - word3_muladd(&w2, &w1, &w0, ws[12], p[3]); - word3_muladd(&w2, &w1, &w0, ws[13], p[2]); - word3_muladd(&w2, &w1, &w0, ws[14], p[1]); - word3_add(&w2, &w1, &w0, z[15]); - ws[15] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[15], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[16]); - word3_muladd(&w2, &w1, &w0, ws[1], p[15]); - word3_muladd(&w2, &w1, &w0, ws[2], p[14]); - word3_muladd(&w2, &w1, &w0, ws[3], p[13]); - word3_muladd(&w2, &w1, &w0, ws[4], p[12]); - word3_muladd(&w2, &w1, &w0, ws[5], p[11]); - word3_muladd(&w2, &w1, &w0, ws[6], p[10]); - word3_muladd(&w2, &w1, &w0, ws[7], p[9]); - word3_muladd(&w2, &w1, &w0, ws[8], p[8]); - word3_muladd(&w2, &w1, &w0, ws[9], p[7]); - word3_muladd(&w2, &w1, &w0, ws[10], p[6]); - word3_muladd(&w2, &w1, &w0, ws[11], p[5]); - word3_muladd(&w2, &w1, &w0, ws[12], p[4]); - word3_muladd(&w2, &w1, &w0, ws[13], p[3]); - word3_muladd(&w2, &w1, &w0, ws[14], p[2]); - word3_muladd(&w2, &w1, &w0, ws[15], p[1]); - word3_add(&w2, &w1, &w0, z[16]); - ws[16] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[16], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[17]); - word3_muladd(&w2, &w1, &w0, ws[1], p[16]); - word3_muladd(&w2, &w1, &w0, ws[2], p[15]); - word3_muladd(&w2, &w1, &w0, ws[3], p[14]); - word3_muladd(&w2, &w1, &w0, ws[4], p[13]); - word3_muladd(&w2, &w1, &w0, ws[5], p[12]); - word3_muladd(&w2, &w1, &w0, ws[6], p[11]); - word3_muladd(&w2, &w1, &w0, ws[7], p[10]); - word3_muladd(&w2, &w1, &w0, ws[8], p[9]); - word3_muladd(&w2, &w1, &w0, ws[9], p[8]); - word3_muladd(&w2, &w1, &w0, ws[10], p[7]); - word3_muladd(&w2, &w1, &w0, ws[11], p[6]); - word3_muladd(&w2, &w1, &w0, ws[12], p[5]); - word3_muladd(&w2, &w1, &w0, ws[13], p[4]); - word3_muladd(&w2, &w1, &w0, ws[14], p[3]); - word3_muladd(&w2, &w1, &w0, ws[15], p[2]); - word3_muladd(&w2, &w1, &w0, ws[16], p[1]); - word3_add(&w2, &w1, &w0, z[17]); - ws[17] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[17], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[18]); - word3_muladd(&w2, &w1, &w0, ws[1], p[17]); - word3_muladd(&w2, &w1, &w0, ws[2], p[16]); - word3_muladd(&w2, &w1, &w0, ws[3], p[15]); - word3_muladd(&w2, &w1, &w0, ws[4], p[14]); - word3_muladd(&w2, &w1, &w0, ws[5], p[13]); - word3_muladd(&w2, &w1, &w0, ws[6], p[12]); - word3_muladd(&w2, &w1, &w0, ws[7], p[11]); - word3_muladd(&w2, &w1, &w0, ws[8], p[10]); - word3_muladd(&w2, &w1, &w0, ws[9], p[9]); - word3_muladd(&w2, &w1, &w0, ws[10], p[8]); - word3_muladd(&w2, &w1, &w0, ws[11], p[7]); - word3_muladd(&w2, &w1, &w0, ws[12], p[6]); - word3_muladd(&w2, &w1, &w0, ws[13], p[5]); - word3_muladd(&w2, &w1, &w0, ws[14], p[4]); - word3_muladd(&w2, &w1, &w0, ws[15], p[3]); - word3_muladd(&w2, &w1, &w0, ws[16], p[2]); - word3_muladd(&w2, &w1, &w0, ws[17], p[1]); - word3_add(&w2, &w1, &w0, z[18]); - ws[18] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[18], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[19]); - word3_muladd(&w2, &w1, &w0, ws[1], p[18]); - word3_muladd(&w2, &w1, &w0, ws[2], p[17]); - word3_muladd(&w2, &w1, &w0, ws[3], p[16]); - word3_muladd(&w2, &w1, &w0, ws[4], p[15]); - word3_muladd(&w2, &w1, &w0, ws[5], p[14]); - word3_muladd(&w2, &w1, &w0, ws[6], p[13]); - word3_muladd(&w2, &w1, &w0, ws[7], p[12]); - word3_muladd(&w2, &w1, &w0, ws[8], p[11]); - word3_muladd(&w2, &w1, &w0, ws[9], p[10]); - word3_muladd(&w2, &w1, &w0, ws[10], p[9]); - word3_muladd(&w2, &w1, &w0, ws[11], p[8]); - word3_muladd(&w2, &w1, &w0, ws[12], p[7]); - word3_muladd(&w2, &w1, &w0, ws[13], p[6]); - word3_muladd(&w2, &w1, &w0, ws[14], p[5]); - word3_muladd(&w2, &w1, &w0, ws[15], p[4]); - word3_muladd(&w2, &w1, &w0, ws[16], p[3]); - word3_muladd(&w2, &w1, &w0, ws[17], p[2]); - word3_muladd(&w2, &w1, &w0, ws[18], p[1]); - word3_add(&w2, &w1, &w0, z[19]); - ws[19] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[19], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[20]); - word3_muladd(&w2, &w1, &w0, ws[1], p[19]); - word3_muladd(&w2, &w1, &w0, ws[2], p[18]); - word3_muladd(&w2, &w1, &w0, ws[3], p[17]); - word3_muladd(&w2, &w1, &w0, ws[4], p[16]); - word3_muladd(&w2, &w1, &w0, ws[5], p[15]); - word3_muladd(&w2, &w1, &w0, ws[6], p[14]); - word3_muladd(&w2, &w1, &w0, ws[7], p[13]); - word3_muladd(&w2, &w1, &w0, ws[8], p[12]); - word3_muladd(&w2, &w1, &w0, ws[9], p[11]); - word3_muladd(&w2, &w1, &w0, ws[10], p[10]); - word3_muladd(&w2, &w1, &w0, ws[11], p[9]); - word3_muladd(&w2, &w1, &w0, ws[12], p[8]); - word3_muladd(&w2, &w1, &w0, ws[13], p[7]); - word3_muladd(&w2, &w1, &w0, ws[14], p[6]); - word3_muladd(&w2, &w1, &w0, ws[15], p[5]); - word3_muladd(&w2, &w1, &w0, ws[16], p[4]); - word3_muladd(&w2, &w1, &w0, ws[17], p[3]); - word3_muladd(&w2, &w1, &w0, ws[18], p[2]); - word3_muladd(&w2, &w1, &w0, ws[19], p[1]); - word3_add(&w2, &w1, &w0, z[20]); - ws[20] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[20], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[21]); - word3_muladd(&w2, &w1, &w0, ws[1], p[20]); - word3_muladd(&w2, &w1, &w0, ws[2], p[19]); - word3_muladd(&w2, &w1, &w0, ws[3], p[18]); - word3_muladd(&w2, &w1, &w0, ws[4], p[17]); - word3_muladd(&w2, &w1, &w0, ws[5], p[16]); - word3_muladd(&w2, &w1, &w0, ws[6], p[15]); - word3_muladd(&w2, &w1, &w0, ws[7], p[14]); - word3_muladd(&w2, &w1, &w0, ws[8], p[13]); - word3_muladd(&w2, &w1, &w0, ws[9], p[12]); - word3_muladd(&w2, &w1, &w0, ws[10], p[11]); - word3_muladd(&w2, &w1, &w0, ws[11], p[10]); - word3_muladd(&w2, &w1, &w0, ws[12], p[9]); - word3_muladd(&w2, &w1, &w0, ws[13], p[8]); - word3_muladd(&w2, &w1, &w0, ws[14], p[7]); - word3_muladd(&w2, &w1, &w0, ws[15], p[6]); - word3_muladd(&w2, &w1, &w0, ws[16], p[5]); - word3_muladd(&w2, &w1, &w0, ws[17], p[4]); - word3_muladd(&w2, &w1, &w0, ws[18], p[3]); - word3_muladd(&w2, &w1, &w0, ws[19], p[2]); - word3_muladd(&w2, &w1, &w0, ws[20], p[1]); - word3_add(&w2, &w1, &w0, z[21]); - ws[21] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[21], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[22]); - word3_muladd(&w2, &w1, &w0, ws[1], p[21]); - word3_muladd(&w2, &w1, &w0, ws[2], p[20]); - word3_muladd(&w2, &w1, &w0, ws[3], p[19]); - word3_muladd(&w2, &w1, &w0, ws[4], p[18]); - word3_muladd(&w2, &w1, &w0, ws[5], p[17]); - word3_muladd(&w2, &w1, &w0, ws[6], p[16]); - word3_muladd(&w2, &w1, &w0, ws[7], p[15]); - word3_muladd(&w2, &w1, &w0, ws[8], p[14]); - word3_muladd(&w2, &w1, &w0, ws[9], p[13]); - word3_muladd(&w2, &w1, &w0, ws[10], p[12]); - word3_muladd(&w2, &w1, &w0, ws[11], p[11]); - word3_muladd(&w2, &w1, &w0, ws[12], p[10]); - word3_muladd(&w2, &w1, &w0, ws[13], p[9]); - word3_muladd(&w2, &w1, &w0, ws[14], p[8]); - word3_muladd(&w2, &w1, &w0, ws[15], p[7]); - word3_muladd(&w2, &w1, &w0, ws[16], p[6]); - word3_muladd(&w2, &w1, &w0, ws[17], p[5]); - word3_muladd(&w2, &w1, &w0, ws[18], p[4]); - word3_muladd(&w2, &w1, &w0, ws[19], p[3]); - word3_muladd(&w2, &w1, &w0, ws[20], p[2]); - word3_muladd(&w2, &w1, &w0, ws[21], p[1]); - word3_add(&w2, &w1, &w0, z[22]); - ws[22] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[22], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[23]); - word3_muladd(&w2, &w1, &w0, ws[1], p[22]); - word3_muladd(&w2, &w1, &w0, ws[2], p[21]); - word3_muladd(&w2, &w1, &w0, ws[3], p[20]); - word3_muladd(&w2, &w1, &w0, ws[4], p[19]); - word3_muladd(&w2, &w1, &w0, ws[5], p[18]); - word3_muladd(&w2, &w1, &w0, ws[6], p[17]); - word3_muladd(&w2, &w1, &w0, ws[7], p[16]); - word3_muladd(&w2, &w1, &w0, ws[8], p[15]); - word3_muladd(&w2, &w1, &w0, ws[9], p[14]); - word3_muladd(&w2, &w1, &w0, ws[10], p[13]); - word3_muladd(&w2, &w1, &w0, ws[11], p[12]); - word3_muladd(&w2, &w1, &w0, ws[12], p[11]); - word3_muladd(&w2, &w1, &w0, ws[13], p[10]); - word3_muladd(&w2, &w1, &w0, ws[14], p[9]); - word3_muladd(&w2, &w1, &w0, ws[15], p[8]); - word3_muladd(&w2, &w1, &w0, ws[16], p[7]); - word3_muladd(&w2, &w1, &w0, ws[17], p[6]); - word3_muladd(&w2, &w1, &w0, ws[18], p[5]); - word3_muladd(&w2, &w1, &w0, ws[19], p[4]); - word3_muladd(&w2, &w1, &w0, ws[20], p[3]); - word3_muladd(&w2, &w1, &w0, ws[21], p[2]); - word3_muladd(&w2, &w1, &w0, ws[22], p[1]); - word3_add(&w2, &w1, &w0, z[23]); - ws[23] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[23], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[24]); - word3_muladd(&w2, &w1, &w0, ws[1], p[23]); - word3_muladd(&w2, &w1, &w0, ws[2], p[22]); - word3_muladd(&w2, &w1, &w0, ws[3], p[21]); - word3_muladd(&w2, &w1, &w0, ws[4], p[20]); - word3_muladd(&w2, &w1, &w0, ws[5], p[19]); - word3_muladd(&w2, &w1, &w0, ws[6], p[18]); - word3_muladd(&w2, &w1, &w0, ws[7], p[17]); - word3_muladd(&w2, &w1, &w0, ws[8], p[16]); - word3_muladd(&w2, &w1, &w0, ws[9], p[15]); - word3_muladd(&w2, &w1, &w0, ws[10], p[14]); - word3_muladd(&w2, &w1, &w0, ws[11], p[13]); - word3_muladd(&w2, &w1, &w0, ws[12], p[12]); - word3_muladd(&w2, &w1, &w0, ws[13], p[11]); - word3_muladd(&w2, &w1, &w0, ws[14], p[10]); - word3_muladd(&w2, &w1, &w0, ws[15], p[9]); - word3_muladd(&w2, &w1, &w0, ws[16], p[8]); - word3_muladd(&w2, &w1, &w0, ws[17], p[7]); - word3_muladd(&w2, &w1, &w0, ws[18], p[6]); - word3_muladd(&w2, &w1, &w0, ws[19], p[5]); - word3_muladd(&w2, &w1, &w0, ws[20], p[4]); - word3_muladd(&w2, &w1, &w0, ws[21], p[3]); - word3_muladd(&w2, &w1, &w0, ws[22], p[2]); - word3_muladd(&w2, &w1, &w0, ws[23], p[1]); - word3_add(&w2, &w1, &w0, z[24]); - ws[24] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[24], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[25]); - word3_muladd(&w2, &w1, &w0, ws[1], p[24]); - word3_muladd(&w2, &w1, &w0, ws[2], p[23]); - word3_muladd(&w2, &w1, &w0, ws[3], p[22]); - word3_muladd(&w2, &w1, &w0, ws[4], p[21]); - word3_muladd(&w2, &w1, &w0, ws[5], p[20]); - word3_muladd(&w2, &w1, &w0, ws[6], p[19]); - word3_muladd(&w2, &w1, &w0, ws[7], p[18]); - word3_muladd(&w2, &w1, &w0, ws[8], p[17]); - word3_muladd(&w2, &w1, &w0, ws[9], p[16]); - word3_muladd(&w2, &w1, &w0, ws[10], p[15]); - word3_muladd(&w2, &w1, &w0, ws[11], p[14]); - word3_muladd(&w2, &w1, &w0, ws[12], p[13]); - word3_muladd(&w2, &w1, &w0, ws[13], p[12]); - word3_muladd(&w2, &w1, &w0, ws[14], p[11]); - word3_muladd(&w2, &w1, &w0, ws[15], p[10]); - word3_muladd(&w2, &w1, &w0, ws[16], p[9]); - word3_muladd(&w2, &w1, &w0, ws[17], p[8]); - word3_muladd(&w2, &w1, &w0, ws[18], p[7]); - word3_muladd(&w2, &w1, &w0, ws[19], p[6]); - word3_muladd(&w2, &w1, &w0, ws[20], p[5]); - word3_muladd(&w2, &w1, &w0, ws[21], p[4]); - word3_muladd(&w2, &w1, &w0, ws[22], p[3]); - word3_muladd(&w2, &w1, &w0, ws[23], p[2]); - word3_muladd(&w2, &w1, &w0, ws[24], p[1]); - word3_add(&w2, &w1, &w0, z[25]); - ws[25] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[25], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[26]); - word3_muladd(&w2, &w1, &w0, ws[1], p[25]); - word3_muladd(&w2, &w1, &w0, ws[2], p[24]); - word3_muladd(&w2, &w1, &w0, ws[3], p[23]); - word3_muladd(&w2, &w1, &w0, ws[4], p[22]); - word3_muladd(&w2, &w1, &w0, ws[5], p[21]); - word3_muladd(&w2, &w1, &w0, ws[6], p[20]); - word3_muladd(&w2, &w1, &w0, ws[7], p[19]); - word3_muladd(&w2, &w1, &w0, ws[8], p[18]); - word3_muladd(&w2, &w1, &w0, ws[9], p[17]); - word3_muladd(&w2, &w1, &w0, ws[10], p[16]); - word3_muladd(&w2, &w1, &w0, ws[11], p[15]); - word3_muladd(&w2, &w1, &w0, ws[12], p[14]); - word3_muladd(&w2, &w1, &w0, ws[13], p[13]); - word3_muladd(&w2, &w1, &w0, ws[14], p[12]); - word3_muladd(&w2, &w1, &w0, ws[15], p[11]); - word3_muladd(&w2, &w1, &w0, ws[16], p[10]); - word3_muladd(&w2, &w1, &w0, ws[17], p[9]); - word3_muladd(&w2, &w1, &w0, ws[18], p[8]); - word3_muladd(&w2, &w1, &w0, ws[19], p[7]); - word3_muladd(&w2, &w1, &w0, ws[20], p[6]); - word3_muladd(&w2, &w1, &w0, ws[21], p[5]); - word3_muladd(&w2, &w1, &w0, ws[22], p[4]); - word3_muladd(&w2, &w1, &w0, ws[23], p[3]); - word3_muladd(&w2, &w1, &w0, ws[24], p[2]); - word3_muladd(&w2, &w1, &w0, ws[25], p[1]); - word3_add(&w2, &w1, &w0, z[26]); - ws[26] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[26], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[27]); - word3_muladd(&w2, &w1, &w0, ws[1], p[26]); - word3_muladd(&w2, &w1, &w0, ws[2], p[25]); - word3_muladd(&w2, &w1, &w0, ws[3], p[24]); - word3_muladd(&w2, &w1, &w0, ws[4], p[23]); - word3_muladd(&w2, &w1, &w0, ws[5], p[22]); - word3_muladd(&w2, &w1, &w0, ws[6], p[21]); - word3_muladd(&w2, &w1, &w0, ws[7], p[20]); - word3_muladd(&w2, &w1, &w0, ws[8], p[19]); - word3_muladd(&w2, &w1, &w0, ws[9], p[18]); - word3_muladd(&w2, &w1, &w0, ws[10], p[17]); - word3_muladd(&w2, &w1, &w0, ws[11], p[16]); - word3_muladd(&w2, &w1, &w0, ws[12], p[15]); - word3_muladd(&w2, &w1, &w0, ws[13], p[14]); - word3_muladd(&w2, &w1, &w0, ws[14], p[13]); - word3_muladd(&w2, &w1, &w0, ws[15], p[12]); - word3_muladd(&w2, &w1, &w0, ws[16], p[11]); - word3_muladd(&w2, &w1, &w0, ws[17], p[10]); - word3_muladd(&w2, &w1, &w0, ws[18], p[9]); - word3_muladd(&w2, &w1, &w0, ws[19], p[8]); - word3_muladd(&w2, &w1, &w0, ws[20], p[7]); - word3_muladd(&w2, &w1, &w0, ws[21], p[6]); - word3_muladd(&w2, &w1, &w0, ws[22], p[5]); - word3_muladd(&w2, &w1, &w0, ws[23], p[4]); - word3_muladd(&w2, &w1, &w0, ws[24], p[3]); - word3_muladd(&w2, &w1, &w0, ws[25], p[2]); - word3_muladd(&w2, &w1, &w0, ws[26], p[1]); - word3_add(&w2, &w1, &w0, z[27]); - ws[27] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[27], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[28]); - word3_muladd(&w2, &w1, &w0, ws[1], p[27]); - word3_muladd(&w2, &w1, &w0, ws[2], p[26]); - word3_muladd(&w2, &w1, &w0, ws[3], p[25]); - word3_muladd(&w2, &w1, &w0, ws[4], p[24]); - word3_muladd(&w2, &w1, &w0, ws[5], p[23]); - word3_muladd(&w2, &w1, &w0, ws[6], p[22]); - word3_muladd(&w2, &w1, &w0, ws[7], p[21]); - word3_muladd(&w2, &w1, &w0, ws[8], p[20]); - word3_muladd(&w2, &w1, &w0, ws[9], p[19]); - word3_muladd(&w2, &w1, &w0, ws[10], p[18]); - word3_muladd(&w2, &w1, &w0, ws[11], p[17]); - word3_muladd(&w2, &w1, &w0, ws[12], p[16]); - word3_muladd(&w2, &w1, &w0, ws[13], p[15]); - word3_muladd(&w2, &w1, &w0, ws[14], p[14]); - word3_muladd(&w2, &w1, &w0, ws[15], p[13]); - word3_muladd(&w2, &w1, &w0, ws[16], p[12]); - word3_muladd(&w2, &w1, &w0, ws[17], p[11]); - word3_muladd(&w2, &w1, &w0, ws[18], p[10]); - word3_muladd(&w2, &w1, &w0, ws[19], p[9]); - word3_muladd(&w2, &w1, &w0, ws[20], p[8]); - word3_muladd(&w2, &w1, &w0, ws[21], p[7]); - word3_muladd(&w2, &w1, &w0, ws[22], p[6]); - word3_muladd(&w2, &w1, &w0, ws[23], p[5]); - word3_muladd(&w2, &w1, &w0, ws[24], p[4]); - word3_muladd(&w2, &w1, &w0, ws[25], p[3]); - word3_muladd(&w2, &w1, &w0, ws[26], p[2]); - word3_muladd(&w2, &w1, &w0, ws[27], p[1]); - word3_add(&w2, &w1, &w0, z[28]); - ws[28] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[28], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[29]); - word3_muladd(&w2, &w1, &w0, ws[1], p[28]); - word3_muladd(&w2, &w1, &w0, ws[2], p[27]); - word3_muladd(&w2, &w1, &w0, ws[3], p[26]); - word3_muladd(&w2, &w1, &w0, ws[4], p[25]); - word3_muladd(&w2, &w1, &w0, ws[5], p[24]); - word3_muladd(&w2, &w1, &w0, ws[6], p[23]); - word3_muladd(&w2, &w1, &w0, ws[7], p[22]); - word3_muladd(&w2, &w1, &w0, ws[8], p[21]); - word3_muladd(&w2, &w1, &w0, ws[9], p[20]); - word3_muladd(&w2, &w1, &w0, ws[10], p[19]); - word3_muladd(&w2, &w1, &w0, ws[11], p[18]); - word3_muladd(&w2, &w1, &w0, ws[12], p[17]); - word3_muladd(&w2, &w1, &w0, ws[13], p[16]); - word3_muladd(&w2, &w1, &w0, ws[14], p[15]); - word3_muladd(&w2, &w1, &w0, ws[15], p[14]); - word3_muladd(&w2, &w1, &w0, ws[16], p[13]); - word3_muladd(&w2, &w1, &w0, ws[17], p[12]); - word3_muladd(&w2, &w1, &w0, ws[18], p[11]); - word3_muladd(&w2, &w1, &w0, ws[19], p[10]); - word3_muladd(&w2, &w1, &w0, ws[20], p[9]); - word3_muladd(&w2, &w1, &w0, ws[21], p[8]); - word3_muladd(&w2, &w1, &w0, ws[22], p[7]); - word3_muladd(&w2, &w1, &w0, ws[23], p[6]); - word3_muladd(&w2, &w1, &w0, ws[24], p[5]); - word3_muladd(&w2, &w1, &w0, ws[25], p[4]); - word3_muladd(&w2, &w1, &w0, ws[26], p[3]); - word3_muladd(&w2, &w1, &w0, ws[27], p[2]); - word3_muladd(&w2, &w1, &w0, ws[28], p[1]); - word3_add(&w2, &w1, &w0, z[29]); - ws[29] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[29], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[30]); - word3_muladd(&w2, &w1, &w0, ws[1], p[29]); - word3_muladd(&w2, &w1, &w0, ws[2], p[28]); - word3_muladd(&w2, &w1, &w0, ws[3], p[27]); - word3_muladd(&w2, &w1, &w0, ws[4], p[26]); - word3_muladd(&w2, &w1, &w0, ws[5], p[25]); - word3_muladd(&w2, &w1, &w0, ws[6], p[24]); - word3_muladd(&w2, &w1, &w0, ws[7], p[23]); - word3_muladd(&w2, &w1, &w0, ws[8], p[22]); - word3_muladd(&w2, &w1, &w0, ws[9], p[21]); - word3_muladd(&w2, &w1, &w0, ws[10], p[20]); - word3_muladd(&w2, &w1, &w0, ws[11], p[19]); - word3_muladd(&w2, &w1, &w0, ws[12], p[18]); - word3_muladd(&w2, &w1, &w0, ws[13], p[17]); - word3_muladd(&w2, &w1, &w0, ws[14], p[16]); - word3_muladd(&w2, &w1, &w0, ws[15], p[15]); - word3_muladd(&w2, &w1, &w0, ws[16], p[14]); - word3_muladd(&w2, &w1, &w0, ws[17], p[13]); - word3_muladd(&w2, &w1, &w0, ws[18], p[12]); - word3_muladd(&w2, &w1, &w0, ws[19], p[11]); - word3_muladd(&w2, &w1, &w0, ws[20], p[10]); - word3_muladd(&w2, &w1, &w0, ws[21], p[9]); - word3_muladd(&w2, &w1, &w0, ws[22], p[8]); - word3_muladd(&w2, &w1, &w0, ws[23], p[7]); - word3_muladd(&w2, &w1, &w0, ws[24], p[6]); - word3_muladd(&w2, &w1, &w0, ws[25], p[5]); - word3_muladd(&w2, &w1, &w0, ws[26], p[4]); - word3_muladd(&w2, &w1, &w0, ws[27], p[3]); - word3_muladd(&w2, &w1, &w0, ws[28], p[2]); - word3_muladd(&w2, &w1, &w0, ws[29], p[1]); - word3_add(&w2, &w1, &w0, z[30]); - ws[30] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[30], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[0], p[31]); - word3_muladd(&w2, &w1, &w0, ws[1], p[30]); - word3_muladd(&w2, &w1, &w0, ws[2], p[29]); - word3_muladd(&w2, &w1, &w0, ws[3], p[28]); - word3_muladd(&w2, &w1, &w0, ws[4], p[27]); - word3_muladd(&w2, &w1, &w0, ws[5], p[26]); - word3_muladd(&w2, &w1, &w0, ws[6], p[25]); - word3_muladd(&w2, &w1, &w0, ws[7], p[24]); - word3_muladd(&w2, &w1, &w0, ws[8], p[23]); - word3_muladd(&w2, &w1, &w0, ws[9], p[22]); - word3_muladd(&w2, &w1, &w0, ws[10], p[21]); - word3_muladd(&w2, &w1, &w0, ws[11], p[20]); - word3_muladd(&w2, &w1, &w0, ws[12], p[19]); - word3_muladd(&w2, &w1, &w0, ws[13], p[18]); - word3_muladd(&w2, &w1, &w0, ws[14], p[17]); - word3_muladd(&w2, &w1, &w0, ws[15], p[16]); - word3_muladd(&w2, &w1, &w0, ws[16], p[15]); - word3_muladd(&w2, &w1, &w0, ws[17], p[14]); - word3_muladd(&w2, &w1, &w0, ws[18], p[13]); - word3_muladd(&w2, &w1, &w0, ws[19], p[12]); - word3_muladd(&w2, &w1, &w0, ws[20], p[11]); - word3_muladd(&w2, &w1, &w0, ws[21], p[10]); - word3_muladd(&w2, &w1, &w0, ws[22], p[9]); - word3_muladd(&w2, &w1, &w0, ws[23], p[8]); - word3_muladd(&w2, &w1, &w0, ws[24], p[7]); - word3_muladd(&w2, &w1, &w0, ws[25], p[6]); - word3_muladd(&w2, &w1, &w0, ws[26], p[5]); - word3_muladd(&w2, &w1, &w0, ws[27], p[4]); - word3_muladd(&w2, &w1, &w0, ws[28], p[3]); - word3_muladd(&w2, &w1, &w0, ws[29], p[2]); - word3_muladd(&w2, &w1, &w0, ws[30], p[1]); - word3_add(&w2, &w1, &w0, z[31]); - ws[31] = w0 * p_dash; - word3_muladd(&w2, &w1, &w0, ws[31], p[0]); - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[1], p[31]); - word3_muladd(&w2, &w1, &w0, ws[2], p[30]); - word3_muladd(&w2, &w1, &w0, ws[3], p[29]); - word3_muladd(&w2, &w1, &w0, ws[4], p[28]); - word3_muladd(&w2, &w1, &w0, ws[5], p[27]); - word3_muladd(&w2, &w1, &w0, ws[6], p[26]); - word3_muladd(&w2, &w1, &w0, ws[7], p[25]); - word3_muladd(&w2, &w1, &w0, ws[8], p[24]); - word3_muladd(&w2, &w1, &w0, ws[9], p[23]); - word3_muladd(&w2, &w1, &w0, ws[10], p[22]); - word3_muladd(&w2, &w1, &w0, ws[11], p[21]); - word3_muladd(&w2, &w1, &w0, ws[12], p[20]); - word3_muladd(&w2, &w1, &w0, ws[13], p[19]); - word3_muladd(&w2, &w1, &w0, ws[14], p[18]); - word3_muladd(&w2, &w1, &w0, ws[15], p[17]); - word3_muladd(&w2, &w1, &w0, ws[16], p[16]); - word3_muladd(&w2, &w1, &w0, ws[17], p[15]); - word3_muladd(&w2, &w1, &w0, ws[18], p[14]); - word3_muladd(&w2, &w1, &w0, ws[19], p[13]); - word3_muladd(&w2, &w1, &w0, ws[20], p[12]); - word3_muladd(&w2, &w1, &w0, ws[21], p[11]); - word3_muladd(&w2, &w1, &w0, ws[22], p[10]); - word3_muladd(&w2, &w1, &w0, ws[23], p[9]); - word3_muladd(&w2, &w1, &w0, ws[24], p[8]); - word3_muladd(&w2, &w1, &w0, ws[25], p[7]); - word3_muladd(&w2, &w1, &w0, ws[26], p[6]); - word3_muladd(&w2, &w1, &w0, ws[27], p[5]); - word3_muladd(&w2, &w1, &w0, ws[28], p[4]); - word3_muladd(&w2, &w1, &w0, ws[29], p[3]); - word3_muladd(&w2, &w1, &w0, ws[30], p[2]); - word3_muladd(&w2, &w1, &w0, ws[31], p[1]); - word3_add(&w2, &w1, &w0, z[32]); - ws[0] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[2], p[31]); - word3_muladd(&w2, &w1, &w0, ws[3], p[30]); - word3_muladd(&w2, &w1, &w0, ws[4], p[29]); - word3_muladd(&w2, &w1, &w0, ws[5], p[28]); - word3_muladd(&w2, &w1, &w0, ws[6], p[27]); - word3_muladd(&w2, &w1, &w0, ws[7], p[26]); - word3_muladd(&w2, &w1, &w0, ws[8], p[25]); - word3_muladd(&w2, &w1, &w0, ws[9], p[24]); - word3_muladd(&w2, &w1, &w0, ws[10], p[23]); - word3_muladd(&w2, &w1, &w0, ws[11], p[22]); - word3_muladd(&w2, &w1, &w0, ws[12], p[21]); - word3_muladd(&w2, &w1, &w0, ws[13], p[20]); - word3_muladd(&w2, &w1, &w0, ws[14], p[19]); - word3_muladd(&w2, &w1, &w0, ws[15], p[18]); - word3_muladd(&w2, &w1, &w0, ws[16], p[17]); - word3_muladd(&w2, &w1, &w0, ws[17], p[16]); - word3_muladd(&w2, &w1, &w0, ws[18], p[15]); - word3_muladd(&w2, &w1, &w0, ws[19], p[14]); - word3_muladd(&w2, &w1, &w0, ws[20], p[13]); - word3_muladd(&w2, &w1, &w0, ws[21], p[12]); - word3_muladd(&w2, &w1, &w0, ws[22], p[11]); - word3_muladd(&w2, &w1, &w0, ws[23], p[10]); - word3_muladd(&w2, &w1, &w0, ws[24], p[9]); - word3_muladd(&w2, &w1, &w0, ws[25], p[8]); - word3_muladd(&w2, &w1, &w0, ws[26], p[7]); - word3_muladd(&w2, &w1, &w0, ws[27], p[6]); - word3_muladd(&w2, &w1, &w0, ws[28], p[5]); - word3_muladd(&w2, &w1, &w0, ws[29], p[4]); - word3_muladd(&w2, &w1, &w0, ws[30], p[3]); - word3_muladd(&w2, &w1, &w0, ws[31], p[2]); - word3_add(&w2, &w1, &w0, z[33]); - ws[1] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[3], p[31]); - word3_muladd(&w2, &w1, &w0, ws[4], p[30]); - word3_muladd(&w2, &w1, &w0, ws[5], p[29]); - word3_muladd(&w2, &w1, &w0, ws[6], p[28]); - word3_muladd(&w2, &w1, &w0, ws[7], p[27]); - word3_muladd(&w2, &w1, &w0, ws[8], p[26]); - word3_muladd(&w2, &w1, &w0, ws[9], p[25]); - word3_muladd(&w2, &w1, &w0, ws[10], p[24]); - word3_muladd(&w2, &w1, &w0, ws[11], p[23]); - word3_muladd(&w2, &w1, &w0, ws[12], p[22]); - word3_muladd(&w2, &w1, &w0, ws[13], p[21]); - word3_muladd(&w2, &w1, &w0, ws[14], p[20]); - word3_muladd(&w2, &w1, &w0, ws[15], p[19]); - word3_muladd(&w2, &w1, &w0, ws[16], p[18]); - word3_muladd(&w2, &w1, &w0, ws[17], p[17]); - word3_muladd(&w2, &w1, &w0, ws[18], p[16]); - word3_muladd(&w2, &w1, &w0, ws[19], p[15]); - word3_muladd(&w2, &w1, &w0, ws[20], p[14]); - word3_muladd(&w2, &w1, &w0, ws[21], p[13]); - word3_muladd(&w2, &w1, &w0, ws[22], p[12]); - word3_muladd(&w2, &w1, &w0, ws[23], p[11]); - word3_muladd(&w2, &w1, &w0, ws[24], p[10]); - word3_muladd(&w2, &w1, &w0, ws[25], p[9]); - word3_muladd(&w2, &w1, &w0, ws[26], p[8]); - word3_muladd(&w2, &w1, &w0, ws[27], p[7]); - word3_muladd(&w2, &w1, &w0, ws[28], p[6]); - word3_muladd(&w2, &w1, &w0, ws[29], p[5]); - word3_muladd(&w2, &w1, &w0, ws[30], p[4]); - word3_muladd(&w2, &w1, &w0, ws[31], p[3]); - word3_add(&w2, &w1, &w0, z[34]); - ws[2] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[4], p[31]); - word3_muladd(&w2, &w1, &w0, ws[5], p[30]); - word3_muladd(&w2, &w1, &w0, ws[6], p[29]); - word3_muladd(&w2, &w1, &w0, ws[7], p[28]); - word3_muladd(&w2, &w1, &w0, ws[8], p[27]); - word3_muladd(&w2, &w1, &w0, ws[9], p[26]); - word3_muladd(&w2, &w1, &w0, ws[10], p[25]); - word3_muladd(&w2, &w1, &w0, ws[11], p[24]); - word3_muladd(&w2, &w1, &w0, ws[12], p[23]); - word3_muladd(&w2, &w1, &w0, ws[13], p[22]); - word3_muladd(&w2, &w1, &w0, ws[14], p[21]); - word3_muladd(&w2, &w1, &w0, ws[15], p[20]); - word3_muladd(&w2, &w1, &w0, ws[16], p[19]); - word3_muladd(&w2, &w1, &w0, ws[17], p[18]); - word3_muladd(&w2, &w1, &w0, ws[18], p[17]); - word3_muladd(&w2, &w1, &w0, ws[19], p[16]); - word3_muladd(&w2, &w1, &w0, ws[20], p[15]); - word3_muladd(&w2, &w1, &w0, ws[21], p[14]); - word3_muladd(&w2, &w1, &w0, ws[22], p[13]); - word3_muladd(&w2, &w1, &w0, ws[23], p[12]); - word3_muladd(&w2, &w1, &w0, ws[24], p[11]); - word3_muladd(&w2, &w1, &w0, ws[25], p[10]); - word3_muladd(&w2, &w1, &w0, ws[26], p[9]); - word3_muladd(&w2, &w1, &w0, ws[27], p[8]); - word3_muladd(&w2, &w1, &w0, ws[28], p[7]); - word3_muladd(&w2, &w1, &w0, ws[29], p[6]); - word3_muladd(&w2, &w1, &w0, ws[30], p[5]); - word3_muladd(&w2, &w1, &w0, ws[31], p[4]); - word3_add(&w2, &w1, &w0, z[35]); - ws[3] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[5], p[31]); - word3_muladd(&w2, &w1, &w0, ws[6], p[30]); - word3_muladd(&w2, &w1, &w0, ws[7], p[29]); - word3_muladd(&w2, &w1, &w0, ws[8], p[28]); - word3_muladd(&w2, &w1, &w0, ws[9], p[27]); - word3_muladd(&w2, &w1, &w0, ws[10], p[26]); - word3_muladd(&w2, &w1, &w0, ws[11], p[25]); - word3_muladd(&w2, &w1, &w0, ws[12], p[24]); - word3_muladd(&w2, &w1, &w0, ws[13], p[23]); - word3_muladd(&w2, &w1, &w0, ws[14], p[22]); - word3_muladd(&w2, &w1, &w0, ws[15], p[21]); - word3_muladd(&w2, &w1, &w0, ws[16], p[20]); - word3_muladd(&w2, &w1, &w0, ws[17], p[19]); - word3_muladd(&w2, &w1, &w0, ws[18], p[18]); - word3_muladd(&w2, &w1, &w0, ws[19], p[17]); - word3_muladd(&w2, &w1, &w0, ws[20], p[16]); - word3_muladd(&w2, &w1, &w0, ws[21], p[15]); - word3_muladd(&w2, &w1, &w0, ws[22], p[14]); - word3_muladd(&w2, &w1, &w0, ws[23], p[13]); - word3_muladd(&w2, &w1, &w0, ws[24], p[12]); - word3_muladd(&w2, &w1, &w0, ws[25], p[11]); - word3_muladd(&w2, &w1, &w0, ws[26], p[10]); - word3_muladd(&w2, &w1, &w0, ws[27], p[9]); - word3_muladd(&w2, &w1, &w0, ws[28], p[8]); - word3_muladd(&w2, &w1, &w0, ws[29], p[7]); - word3_muladd(&w2, &w1, &w0, ws[30], p[6]); - word3_muladd(&w2, &w1, &w0, ws[31], p[5]); - word3_add(&w2, &w1, &w0, z[36]); - ws[4] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[6], p[31]); - word3_muladd(&w2, &w1, &w0, ws[7], p[30]); - word3_muladd(&w2, &w1, &w0, ws[8], p[29]); - word3_muladd(&w2, &w1, &w0, ws[9], p[28]); - word3_muladd(&w2, &w1, &w0, ws[10], p[27]); - word3_muladd(&w2, &w1, &w0, ws[11], p[26]); - word3_muladd(&w2, &w1, &w0, ws[12], p[25]); - word3_muladd(&w2, &w1, &w0, ws[13], p[24]); - word3_muladd(&w2, &w1, &w0, ws[14], p[23]); - word3_muladd(&w2, &w1, &w0, ws[15], p[22]); - word3_muladd(&w2, &w1, &w0, ws[16], p[21]); - word3_muladd(&w2, &w1, &w0, ws[17], p[20]); - word3_muladd(&w2, &w1, &w0, ws[18], p[19]); - word3_muladd(&w2, &w1, &w0, ws[19], p[18]); - word3_muladd(&w2, &w1, &w0, ws[20], p[17]); - word3_muladd(&w2, &w1, &w0, ws[21], p[16]); - word3_muladd(&w2, &w1, &w0, ws[22], p[15]); - word3_muladd(&w2, &w1, &w0, ws[23], p[14]); - word3_muladd(&w2, &w1, &w0, ws[24], p[13]); - word3_muladd(&w2, &w1, &w0, ws[25], p[12]); - word3_muladd(&w2, &w1, &w0, ws[26], p[11]); - word3_muladd(&w2, &w1, &w0, ws[27], p[10]); - word3_muladd(&w2, &w1, &w0, ws[28], p[9]); - word3_muladd(&w2, &w1, &w0, ws[29], p[8]); - word3_muladd(&w2, &w1, &w0, ws[30], p[7]); - word3_muladd(&w2, &w1, &w0, ws[31], p[6]); - word3_add(&w2, &w1, &w0, z[37]); - ws[5] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[7], p[31]); - word3_muladd(&w2, &w1, &w0, ws[8], p[30]); - word3_muladd(&w2, &w1, &w0, ws[9], p[29]); - word3_muladd(&w2, &w1, &w0, ws[10], p[28]); - word3_muladd(&w2, &w1, &w0, ws[11], p[27]); - word3_muladd(&w2, &w1, &w0, ws[12], p[26]); - word3_muladd(&w2, &w1, &w0, ws[13], p[25]); - word3_muladd(&w2, &w1, &w0, ws[14], p[24]); - word3_muladd(&w2, &w1, &w0, ws[15], p[23]); - word3_muladd(&w2, &w1, &w0, ws[16], p[22]); - word3_muladd(&w2, &w1, &w0, ws[17], p[21]); - word3_muladd(&w2, &w1, &w0, ws[18], p[20]); - word3_muladd(&w2, &w1, &w0, ws[19], p[19]); - word3_muladd(&w2, &w1, &w0, ws[20], p[18]); - word3_muladd(&w2, &w1, &w0, ws[21], p[17]); - word3_muladd(&w2, &w1, &w0, ws[22], p[16]); - word3_muladd(&w2, &w1, &w0, ws[23], p[15]); - word3_muladd(&w2, &w1, &w0, ws[24], p[14]); - word3_muladd(&w2, &w1, &w0, ws[25], p[13]); - word3_muladd(&w2, &w1, &w0, ws[26], p[12]); - word3_muladd(&w2, &w1, &w0, ws[27], p[11]); - word3_muladd(&w2, &w1, &w0, ws[28], p[10]); - word3_muladd(&w2, &w1, &w0, ws[29], p[9]); - word3_muladd(&w2, &w1, &w0, ws[30], p[8]); - word3_muladd(&w2, &w1, &w0, ws[31], p[7]); - word3_add(&w2, &w1, &w0, z[38]); - ws[6] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[8], p[31]); - word3_muladd(&w2, &w1, &w0, ws[9], p[30]); - word3_muladd(&w2, &w1, &w0, ws[10], p[29]); - word3_muladd(&w2, &w1, &w0, ws[11], p[28]); - word3_muladd(&w2, &w1, &w0, ws[12], p[27]); - word3_muladd(&w2, &w1, &w0, ws[13], p[26]); - word3_muladd(&w2, &w1, &w0, ws[14], p[25]); - word3_muladd(&w2, &w1, &w0, ws[15], p[24]); - word3_muladd(&w2, &w1, &w0, ws[16], p[23]); - word3_muladd(&w2, &w1, &w0, ws[17], p[22]); - word3_muladd(&w2, &w1, &w0, ws[18], p[21]); - word3_muladd(&w2, &w1, &w0, ws[19], p[20]); - word3_muladd(&w2, &w1, &w0, ws[20], p[19]); - word3_muladd(&w2, &w1, &w0, ws[21], p[18]); - word3_muladd(&w2, &w1, &w0, ws[22], p[17]); - word3_muladd(&w2, &w1, &w0, ws[23], p[16]); - word3_muladd(&w2, &w1, &w0, ws[24], p[15]); - word3_muladd(&w2, &w1, &w0, ws[25], p[14]); - word3_muladd(&w2, &w1, &w0, ws[26], p[13]); - word3_muladd(&w2, &w1, &w0, ws[27], p[12]); - word3_muladd(&w2, &w1, &w0, ws[28], p[11]); - word3_muladd(&w2, &w1, &w0, ws[29], p[10]); - word3_muladd(&w2, &w1, &w0, ws[30], p[9]); - word3_muladd(&w2, &w1, &w0, ws[31], p[8]); - word3_add(&w2, &w1, &w0, z[39]); - ws[7] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[9], p[31]); - word3_muladd(&w2, &w1, &w0, ws[10], p[30]); - word3_muladd(&w2, &w1, &w0, ws[11], p[29]); - word3_muladd(&w2, &w1, &w0, ws[12], p[28]); - word3_muladd(&w2, &w1, &w0, ws[13], p[27]); - word3_muladd(&w2, &w1, &w0, ws[14], p[26]); - word3_muladd(&w2, &w1, &w0, ws[15], p[25]); - word3_muladd(&w2, &w1, &w0, ws[16], p[24]); - word3_muladd(&w2, &w1, &w0, ws[17], p[23]); - word3_muladd(&w2, &w1, &w0, ws[18], p[22]); - word3_muladd(&w2, &w1, &w0, ws[19], p[21]); - word3_muladd(&w2, &w1, &w0, ws[20], p[20]); - word3_muladd(&w2, &w1, &w0, ws[21], p[19]); - word3_muladd(&w2, &w1, &w0, ws[22], p[18]); - word3_muladd(&w2, &w1, &w0, ws[23], p[17]); - word3_muladd(&w2, &w1, &w0, ws[24], p[16]); - word3_muladd(&w2, &w1, &w0, ws[25], p[15]); - word3_muladd(&w2, &w1, &w0, ws[26], p[14]); - word3_muladd(&w2, &w1, &w0, ws[27], p[13]); - word3_muladd(&w2, &w1, &w0, ws[28], p[12]); - word3_muladd(&w2, &w1, &w0, ws[29], p[11]); - word3_muladd(&w2, &w1, &w0, ws[30], p[10]); - word3_muladd(&w2, &w1, &w0, ws[31], p[9]); - word3_add(&w2, &w1, &w0, z[40]); - ws[8] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[10], p[31]); - word3_muladd(&w2, &w1, &w0, ws[11], p[30]); - word3_muladd(&w2, &w1, &w0, ws[12], p[29]); - word3_muladd(&w2, &w1, &w0, ws[13], p[28]); - word3_muladd(&w2, &w1, &w0, ws[14], p[27]); - word3_muladd(&w2, &w1, &w0, ws[15], p[26]); - word3_muladd(&w2, &w1, &w0, ws[16], p[25]); - word3_muladd(&w2, &w1, &w0, ws[17], p[24]); - word3_muladd(&w2, &w1, &w0, ws[18], p[23]); - word3_muladd(&w2, &w1, &w0, ws[19], p[22]); - word3_muladd(&w2, &w1, &w0, ws[20], p[21]); - word3_muladd(&w2, &w1, &w0, ws[21], p[20]); - word3_muladd(&w2, &w1, &w0, ws[22], p[19]); - word3_muladd(&w2, &w1, &w0, ws[23], p[18]); - word3_muladd(&w2, &w1, &w0, ws[24], p[17]); - word3_muladd(&w2, &w1, &w0, ws[25], p[16]); - word3_muladd(&w2, &w1, &w0, ws[26], p[15]); - word3_muladd(&w2, &w1, &w0, ws[27], p[14]); - word3_muladd(&w2, &w1, &w0, ws[28], p[13]); - word3_muladd(&w2, &w1, &w0, ws[29], p[12]); - word3_muladd(&w2, &w1, &w0, ws[30], p[11]); - word3_muladd(&w2, &w1, &w0, ws[31], p[10]); - word3_add(&w2, &w1, &w0, z[41]); - ws[9] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[11], p[31]); - word3_muladd(&w2, &w1, &w0, ws[12], p[30]); - word3_muladd(&w2, &w1, &w0, ws[13], p[29]); - word3_muladd(&w2, &w1, &w0, ws[14], p[28]); - word3_muladd(&w2, &w1, &w0, ws[15], p[27]); - word3_muladd(&w2, &w1, &w0, ws[16], p[26]); - word3_muladd(&w2, &w1, &w0, ws[17], p[25]); - word3_muladd(&w2, &w1, &w0, ws[18], p[24]); - word3_muladd(&w2, &w1, &w0, ws[19], p[23]); - word3_muladd(&w2, &w1, &w0, ws[20], p[22]); - word3_muladd(&w2, &w1, &w0, ws[21], p[21]); - word3_muladd(&w2, &w1, &w0, ws[22], p[20]); - word3_muladd(&w2, &w1, &w0, ws[23], p[19]); - word3_muladd(&w2, &w1, &w0, ws[24], p[18]); - word3_muladd(&w2, &w1, &w0, ws[25], p[17]); - word3_muladd(&w2, &w1, &w0, ws[26], p[16]); - word3_muladd(&w2, &w1, &w0, ws[27], p[15]); - word3_muladd(&w2, &w1, &w0, ws[28], p[14]); - word3_muladd(&w2, &w1, &w0, ws[29], p[13]); - word3_muladd(&w2, &w1, &w0, ws[30], p[12]); - word3_muladd(&w2, &w1, &w0, ws[31], p[11]); - word3_add(&w2, &w1, &w0, z[42]); - ws[10] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[12], p[31]); - word3_muladd(&w2, &w1, &w0, ws[13], p[30]); - word3_muladd(&w2, &w1, &w0, ws[14], p[29]); - word3_muladd(&w2, &w1, &w0, ws[15], p[28]); - word3_muladd(&w2, &w1, &w0, ws[16], p[27]); - word3_muladd(&w2, &w1, &w0, ws[17], p[26]); - word3_muladd(&w2, &w1, &w0, ws[18], p[25]); - word3_muladd(&w2, &w1, &w0, ws[19], p[24]); - word3_muladd(&w2, &w1, &w0, ws[20], p[23]); - word3_muladd(&w2, &w1, &w0, ws[21], p[22]); - word3_muladd(&w2, &w1, &w0, ws[22], p[21]); - word3_muladd(&w2, &w1, &w0, ws[23], p[20]); - word3_muladd(&w2, &w1, &w0, ws[24], p[19]); - word3_muladd(&w2, &w1, &w0, ws[25], p[18]); - word3_muladd(&w2, &w1, &w0, ws[26], p[17]); - word3_muladd(&w2, &w1, &w0, ws[27], p[16]); - word3_muladd(&w2, &w1, &w0, ws[28], p[15]); - word3_muladd(&w2, &w1, &w0, ws[29], p[14]); - word3_muladd(&w2, &w1, &w0, ws[30], p[13]); - word3_muladd(&w2, &w1, &w0, ws[31], p[12]); - word3_add(&w2, &w1, &w0, z[43]); - ws[11] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[13], p[31]); - word3_muladd(&w2, &w1, &w0, ws[14], p[30]); - word3_muladd(&w2, &w1, &w0, ws[15], p[29]); - word3_muladd(&w2, &w1, &w0, ws[16], p[28]); - word3_muladd(&w2, &w1, &w0, ws[17], p[27]); - word3_muladd(&w2, &w1, &w0, ws[18], p[26]); - word3_muladd(&w2, &w1, &w0, ws[19], p[25]); - word3_muladd(&w2, &w1, &w0, ws[20], p[24]); - word3_muladd(&w2, &w1, &w0, ws[21], p[23]); - word3_muladd(&w2, &w1, &w0, ws[22], p[22]); - word3_muladd(&w2, &w1, &w0, ws[23], p[21]); - word3_muladd(&w2, &w1, &w0, ws[24], p[20]); - word3_muladd(&w2, &w1, &w0, ws[25], p[19]); - word3_muladd(&w2, &w1, &w0, ws[26], p[18]); - word3_muladd(&w2, &w1, &w0, ws[27], p[17]); - word3_muladd(&w2, &w1, &w0, ws[28], p[16]); - word3_muladd(&w2, &w1, &w0, ws[29], p[15]); - word3_muladd(&w2, &w1, &w0, ws[30], p[14]); - word3_muladd(&w2, &w1, &w0, ws[31], p[13]); - word3_add(&w2, &w1, &w0, z[44]); - ws[12] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[14], p[31]); - word3_muladd(&w2, &w1, &w0, ws[15], p[30]); - word3_muladd(&w2, &w1, &w0, ws[16], p[29]); - word3_muladd(&w2, &w1, &w0, ws[17], p[28]); - word3_muladd(&w2, &w1, &w0, ws[18], p[27]); - word3_muladd(&w2, &w1, &w0, ws[19], p[26]); - word3_muladd(&w2, &w1, &w0, ws[20], p[25]); - word3_muladd(&w2, &w1, &w0, ws[21], p[24]); - word3_muladd(&w2, &w1, &w0, ws[22], p[23]); - word3_muladd(&w2, &w1, &w0, ws[23], p[22]); - word3_muladd(&w2, &w1, &w0, ws[24], p[21]); - word3_muladd(&w2, &w1, &w0, ws[25], p[20]); - word3_muladd(&w2, &w1, &w0, ws[26], p[19]); - word3_muladd(&w2, &w1, &w0, ws[27], p[18]); - word3_muladd(&w2, &w1, &w0, ws[28], p[17]); - word3_muladd(&w2, &w1, &w0, ws[29], p[16]); - word3_muladd(&w2, &w1, &w0, ws[30], p[15]); - word3_muladd(&w2, &w1, &w0, ws[31], p[14]); - word3_add(&w2, &w1, &w0, z[45]); - ws[13] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[15], p[31]); - word3_muladd(&w2, &w1, &w0, ws[16], p[30]); - word3_muladd(&w2, &w1, &w0, ws[17], p[29]); - word3_muladd(&w2, &w1, &w0, ws[18], p[28]); - word3_muladd(&w2, &w1, &w0, ws[19], p[27]); - word3_muladd(&w2, &w1, &w0, ws[20], p[26]); - word3_muladd(&w2, &w1, &w0, ws[21], p[25]); - word3_muladd(&w2, &w1, &w0, ws[22], p[24]); - word3_muladd(&w2, &w1, &w0, ws[23], p[23]); - word3_muladd(&w2, &w1, &w0, ws[24], p[22]); - word3_muladd(&w2, &w1, &w0, ws[25], p[21]); - word3_muladd(&w2, &w1, &w0, ws[26], p[20]); - word3_muladd(&w2, &w1, &w0, ws[27], p[19]); - word3_muladd(&w2, &w1, &w0, ws[28], p[18]); - word3_muladd(&w2, &w1, &w0, ws[29], p[17]); - word3_muladd(&w2, &w1, &w0, ws[30], p[16]); - word3_muladd(&w2, &w1, &w0, ws[31], p[15]); - word3_add(&w2, &w1, &w0, z[46]); - ws[14] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[16], p[31]); - word3_muladd(&w2, &w1, &w0, ws[17], p[30]); - word3_muladd(&w2, &w1, &w0, ws[18], p[29]); - word3_muladd(&w2, &w1, &w0, ws[19], p[28]); - word3_muladd(&w2, &w1, &w0, ws[20], p[27]); - word3_muladd(&w2, &w1, &w0, ws[21], p[26]); - word3_muladd(&w2, &w1, &w0, ws[22], p[25]); - word3_muladd(&w2, &w1, &w0, ws[23], p[24]); - word3_muladd(&w2, &w1, &w0, ws[24], p[23]); - word3_muladd(&w2, &w1, &w0, ws[25], p[22]); - word3_muladd(&w2, &w1, &w0, ws[26], p[21]); - word3_muladd(&w2, &w1, &w0, ws[27], p[20]); - word3_muladd(&w2, &w1, &w0, ws[28], p[19]); - word3_muladd(&w2, &w1, &w0, ws[29], p[18]); - word3_muladd(&w2, &w1, &w0, ws[30], p[17]); - word3_muladd(&w2, &w1, &w0, ws[31], p[16]); - word3_add(&w2, &w1, &w0, z[47]); - ws[15] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[17], p[31]); - word3_muladd(&w2, &w1, &w0, ws[18], p[30]); - word3_muladd(&w2, &w1, &w0, ws[19], p[29]); - word3_muladd(&w2, &w1, &w0, ws[20], p[28]); - word3_muladd(&w2, &w1, &w0, ws[21], p[27]); - word3_muladd(&w2, &w1, &w0, ws[22], p[26]); - word3_muladd(&w2, &w1, &w0, ws[23], p[25]); - word3_muladd(&w2, &w1, &w0, ws[24], p[24]); - word3_muladd(&w2, &w1, &w0, ws[25], p[23]); - word3_muladd(&w2, &w1, &w0, ws[26], p[22]); - word3_muladd(&w2, &w1, &w0, ws[27], p[21]); - word3_muladd(&w2, &w1, &w0, ws[28], p[20]); - word3_muladd(&w2, &w1, &w0, ws[29], p[19]); - word3_muladd(&w2, &w1, &w0, ws[30], p[18]); - word3_muladd(&w2, &w1, &w0, ws[31], p[17]); - word3_add(&w2, &w1, &w0, z[48]); - ws[16] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[18], p[31]); - word3_muladd(&w2, &w1, &w0, ws[19], p[30]); - word3_muladd(&w2, &w1, &w0, ws[20], p[29]); - word3_muladd(&w2, &w1, &w0, ws[21], p[28]); - word3_muladd(&w2, &w1, &w0, ws[22], p[27]); - word3_muladd(&w2, &w1, &w0, ws[23], p[26]); - word3_muladd(&w2, &w1, &w0, ws[24], p[25]); - word3_muladd(&w2, &w1, &w0, ws[25], p[24]); - word3_muladd(&w2, &w1, &w0, ws[26], p[23]); - word3_muladd(&w2, &w1, &w0, ws[27], p[22]); - word3_muladd(&w2, &w1, &w0, ws[28], p[21]); - word3_muladd(&w2, &w1, &w0, ws[29], p[20]); - word3_muladd(&w2, &w1, &w0, ws[30], p[19]); - word3_muladd(&w2, &w1, &w0, ws[31], p[18]); - word3_add(&w2, &w1, &w0, z[49]); - ws[17] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[19], p[31]); - word3_muladd(&w2, &w1, &w0, ws[20], p[30]); - word3_muladd(&w2, &w1, &w0, ws[21], p[29]); - word3_muladd(&w2, &w1, &w0, ws[22], p[28]); - word3_muladd(&w2, &w1, &w0, ws[23], p[27]); - word3_muladd(&w2, &w1, &w0, ws[24], p[26]); - word3_muladd(&w2, &w1, &w0, ws[25], p[25]); - word3_muladd(&w2, &w1, &w0, ws[26], p[24]); - word3_muladd(&w2, &w1, &w0, ws[27], p[23]); - word3_muladd(&w2, &w1, &w0, ws[28], p[22]); - word3_muladd(&w2, &w1, &w0, ws[29], p[21]); - word3_muladd(&w2, &w1, &w0, ws[30], p[20]); - word3_muladd(&w2, &w1, &w0, ws[31], p[19]); - word3_add(&w2, &w1, &w0, z[50]); - ws[18] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[20], p[31]); - word3_muladd(&w2, &w1, &w0, ws[21], p[30]); - word3_muladd(&w2, &w1, &w0, ws[22], p[29]); - word3_muladd(&w2, &w1, &w0, ws[23], p[28]); - word3_muladd(&w2, &w1, &w0, ws[24], p[27]); - word3_muladd(&w2, &w1, &w0, ws[25], p[26]); - word3_muladd(&w2, &w1, &w0, ws[26], p[25]); - word3_muladd(&w2, &w1, &w0, ws[27], p[24]); - word3_muladd(&w2, &w1, &w0, ws[28], p[23]); - word3_muladd(&w2, &w1, &w0, ws[29], p[22]); - word3_muladd(&w2, &w1, &w0, ws[30], p[21]); - word3_muladd(&w2, &w1, &w0, ws[31], p[20]); - word3_add(&w2, &w1, &w0, z[51]); - ws[19] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[21], p[31]); - word3_muladd(&w2, &w1, &w0, ws[22], p[30]); - word3_muladd(&w2, &w1, &w0, ws[23], p[29]); - word3_muladd(&w2, &w1, &w0, ws[24], p[28]); - word3_muladd(&w2, &w1, &w0, ws[25], p[27]); - word3_muladd(&w2, &w1, &w0, ws[26], p[26]); - word3_muladd(&w2, &w1, &w0, ws[27], p[25]); - word3_muladd(&w2, &w1, &w0, ws[28], p[24]); - word3_muladd(&w2, &w1, &w0, ws[29], p[23]); - word3_muladd(&w2, &w1, &w0, ws[30], p[22]); - word3_muladd(&w2, &w1, &w0, ws[31], p[21]); - word3_add(&w2, &w1, &w0, z[52]); - ws[20] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[22], p[31]); - word3_muladd(&w2, &w1, &w0, ws[23], p[30]); - word3_muladd(&w2, &w1, &w0, ws[24], p[29]); - word3_muladd(&w2, &w1, &w0, ws[25], p[28]); - word3_muladd(&w2, &w1, &w0, ws[26], p[27]); - word3_muladd(&w2, &w1, &w0, ws[27], p[26]); - word3_muladd(&w2, &w1, &w0, ws[28], p[25]); - word3_muladd(&w2, &w1, &w0, ws[29], p[24]); - word3_muladd(&w2, &w1, &w0, ws[30], p[23]); - word3_muladd(&w2, &w1, &w0, ws[31], p[22]); - word3_add(&w2, &w1, &w0, z[53]); - ws[21] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[23], p[31]); - word3_muladd(&w2, &w1, &w0, ws[24], p[30]); - word3_muladd(&w2, &w1, &w0, ws[25], p[29]); - word3_muladd(&w2, &w1, &w0, ws[26], p[28]); - word3_muladd(&w2, &w1, &w0, ws[27], p[27]); - word3_muladd(&w2, &w1, &w0, ws[28], p[26]); - word3_muladd(&w2, &w1, &w0, ws[29], p[25]); - word3_muladd(&w2, &w1, &w0, ws[30], p[24]); - word3_muladd(&w2, &w1, &w0, ws[31], p[23]); - word3_add(&w2, &w1, &w0, z[54]); - ws[22] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[24], p[31]); - word3_muladd(&w2, &w1, &w0, ws[25], p[30]); - word3_muladd(&w2, &w1, &w0, ws[26], p[29]); - word3_muladd(&w2, &w1, &w0, ws[27], p[28]); - word3_muladd(&w2, &w1, &w0, ws[28], p[27]); - word3_muladd(&w2, &w1, &w0, ws[29], p[26]); - word3_muladd(&w2, &w1, &w0, ws[30], p[25]); - word3_muladd(&w2, &w1, &w0, ws[31], p[24]); - word3_add(&w2, &w1, &w0, z[55]); - ws[23] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[25], p[31]); - word3_muladd(&w2, &w1, &w0, ws[26], p[30]); - word3_muladd(&w2, &w1, &w0, ws[27], p[29]); - word3_muladd(&w2, &w1, &w0, ws[28], p[28]); - word3_muladd(&w2, &w1, &w0, ws[29], p[27]); - word3_muladd(&w2, &w1, &w0, ws[30], p[26]); - word3_muladd(&w2, &w1, &w0, ws[31], p[25]); - word3_add(&w2, &w1, &w0, z[56]); - ws[24] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[26], p[31]); - word3_muladd(&w2, &w1, &w0, ws[27], p[30]); - word3_muladd(&w2, &w1, &w0, ws[28], p[29]); - word3_muladd(&w2, &w1, &w0, ws[29], p[28]); - word3_muladd(&w2, &w1, &w0, ws[30], p[27]); - word3_muladd(&w2, &w1, &w0, ws[31], p[26]); - word3_add(&w2, &w1, &w0, z[57]); - ws[25] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[27], p[31]); - word3_muladd(&w2, &w1, &w0, ws[28], p[30]); - word3_muladd(&w2, &w1, &w0, ws[29], p[29]); - word3_muladd(&w2, &w1, &w0, ws[30], p[28]); - word3_muladd(&w2, &w1, &w0, ws[31], p[27]); - word3_add(&w2, &w1, &w0, z[58]); - ws[26] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[28], p[31]); - word3_muladd(&w2, &w1, &w0, ws[29], p[30]); - word3_muladd(&w2, &w1, &w0, ws[30], p[29]); - word3_muladd(&w2, &w1, &w0, ws[31], p[28]); - word3_add(&w2, &w1, &w0, z[59]); - ws[27] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[29], p[31]); - word3_muladd(&w2, &w1, &w0, ws[30], p[30]); - word3_muladd(&w2, &w1, &w0, ws[31], p[29]); - word3_add(&w2, &w1, &w0, z[60]); - ws[28] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[30], p[31]); - word3_muladd(&w2, &w1, &w0, ws[31], p[30]); - word3_add(&w2, &w1, &w0, z[61]); - ws[29] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, ws[31], p[31]); - word3_add(&w2, &w1, &w0, z[62]); - ws[30] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[63]); - ws[31] = w0; - w0 = w1; w1 = w2; w2 = 0; - word3_add(&w2, &w1, &w0, z[65]); - ws[32] = w0; - ws[33] = w1; - word borrow = bigint_sub3(ws + 32 + 1, ws, 32 + 1, p, 32); - CT::conditional_copy_mem(borrow, z, ws, ws + 33, 33); - clear_mem(z + 32, 2*(32+1) - 32); - } - +void bigint_monty_redc_4(word z[], const word p[4], word p_dash, word ws[]) { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[0] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_add(&w2, &w1, &w0, z[5]); + ws[1] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_add(&w2, &w1, &w0, z[6]); + ws[2] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[7]); + ws[3] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[9]); + ws[4] = w0; + ws[5] = w1; + word borrow = 0; + ws[5] = word_sub(ws[0], p[0], &borrow); + ws[6] = word_sub(ws[1], p[1], &borrow); + ws[7] = word_sub(ws[2], p[2], &borrow); + ws[8] = word_sub(ws[3], p[3], &borrow); + ws[9] = word_sub(ws[4], 0, &borrow); + CT::conditional_copy_mem(borrow, z, ws, ws + 5, 5); + clear_mem(z + 4, 2 * (4 + 1) - 4); } -/* -* DSA Parameter Generation -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +void bigint_monty_redc_6(word z[], const word p[6], word p_dash, word ws[]) { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[0] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_add(&w2, &w1, &w0, z[7]); + ws[1] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_add(&w2, &w1, &w0, z[8]); + ws[2] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_add(&w2, &w1, &w0, z[9]); + ws[3] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_add(&w2, &w1, &w0, z[10]); + ws[4] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[11]); + ws[5] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[13]); + ws[6] = w0; + ws[7] = w1; + word borrow = 0; + ws[7] = word_sub(ws[0], p[0], &borrow); + ws[8] = word_sub(ws[1], p[1], &borrow); + ws[9] = word_sub(ws[2], p[2], &borrow); + ws[10] = word_sub(ws[3], p[3], &borrow); + ws[11] = word_sub(ws[4], p[4], &borrow); + ws[12] = word_sub(ws[5], p[5], &borrow); + ws[13] = word_sub(ws[6], 0, &borrow); + CT::conditional_copy_mem(borrow, z, ws, ws + 7, 7); + clear_mem(z + 6, 2 * (6 + 1) - 6); +} + +void bigint_monty_redc_8(word z[], const word p[8], word p_dash, word ws[]) { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[6]); + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[6] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[6], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[7]); + word3_muladd(&w2, &w1, &w0, ws[1], p[6]); + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_muladd(&w2, &w1, &w0, ws[6], p[1]); + word3_add(&w2, &w1, &w0, z[7]); + ws[7] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[7], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[7]); + word3_muladd(&w2, &w1, &w0, ws[2], p[6]); + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_muladd(&w2, &w1, &w0, ws[6], p[2]); + word3_muladd(&w2, &w1, &w0, ws[7], p[1]); + word3_add(&w2, &w1, &w0, z[8]); + ws[0] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[7]); + word3_muladd(&w2, &w1, &w0, ws[3], p[6]); + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_muladd(&w2, &w1, &w0, ws[6], p[3]); + word3_muladd(&w2, &w1, &w0, ws[7], p[2]); + word3_add(&w2, &w1, &w0, z[9]); + ws[1] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[7]); + word3_muladd(&w2, &w1, &w0, ws[4], p[6]); + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_muladd(&w2, &w1, &w0, ws[6], p[4]); + word3_muladd(&w2, &w1, &w0, ws[7], p[3]); + word3_add(&w2, &w1, &w0, z[10]); + ws[2] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[7]); + word3_muladd(&w2, &w1, &w0, ws[5], p[6]); + word3_muladd(&w2, &w1, &w0, ws[6], p[5]); + word3_muladd(&w2, &w1, &w0, ws[7], p[4]); + word3_add(&w2, &w1, &w0, z[11]); + ws[3] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[7]); + word3_muladd(&w2, &w1, &w0, ws[6], p[6]); + word3_muladd(&w2, &w1, &w0, ws[7], p[5]); + word3_add(&w2, &w1, &w0, z[12]); + ws[4] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[6], p[7]); + word3_muladd(&w2, &w1, &w0, ws[7], p[6]); + word3_add(&w2, &w1, &w0, z[13]); + ws[5] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[7], p[7]); + word3_add(&w2, &w1, &w0, z[14]); + ws[6] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[15]); + ws[7] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[17]); + ws[8] = w0; + ws[9] = w1; + word borrow = 0; + ws[9] = word_sub(ws[0], p[0], &borrow); + ws[10] = word_sub(ws[1], p[1], &borrow); + ws[11] = word_sub(ws[2], p[2], &borrow); + ws[12] = word_sub(ws[3], p[3], &borrow); + ws[13] = word_sub(ws[4], p[4], &borrow); + ws[14] = word_sub(ws[5], p[5], &borrow); + ws[15] = word_sub(ws[6], p[6], &borrow); + ws[16] = word_sub(ws[7], p[7], &borrow); + ws[17] = word_sub(ws[8], 0, &borrow); + CT::conditional_copy_mem(borrow, z, ws, ws + 9, 9); + clear_mem(z + 8, 2 * (8 + 1) - 8); +} + +void bigint_monty_redc_16(word z[], const word p[16], word p_dash, word ws[]) { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[6]); + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[6] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[6], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[7]); + word3_muladd(&w2, &w1, &w0, ws[1], p[6]); + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_muladd(&w2, &w1, &w0, ws[6], p[1]); + word3_add(&w2, &w1, &w0, z[7]); + ws[7] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[7], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[8]); + word3_muladd(&w2, &w1, &w0, ws[1], p[7]); + word3_muladd(&w2, &w1, &w0, ws[2], p[6]); + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_muladd(&w2, &w1, &w0, ws[6], p[2]); + word3_muladd(&w2, &w1, &w0, ws[7], p[1]); + word3_add(&w2, &w1, &w0, z[8]); + ws[8] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[8], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[9]); + word3_muladd(&w2, &w1, &w0, ws[1], p[8]); + word3_muladd(&w2, &w1, &w0, ws[2], p[7]); + word3_muladd(&w2, &w1, &w0, ws[3], p[6]); + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_muladd(&w2, &w1, &w0, ws[6], p[3]); + word3_muladd(&w2, &w1, &w0, ws[7], p[2]); + word3_muladd(&w2, &w1, &w0, ws[8], p[1]); + word3_add(&w2, &w1, &w0, z[9]); + ws[9] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[9], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[10]); + word3_muladd(&w2, &w1, &w0, ws[1], p[9]); + word3_muladd(&w2, &w1, &w0, ws[2], p[8]); + word3_muladd(&w2, &w1, &w0, ws[3], p[7]); + word3_muladd(&w2, &w1, &w0, ws[4], p[6]); + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_muladd(&w2, &w1, &w0, ws[6], p[4]); + word3_muladd(&w2, &w1, &w0, ws[7], p[3]); + word3_muladd(&w2, &w1, &w0, ws[8], p[2]); + word3_muladd(&w2, &w1, &w0, ws[9], p[1]); + word3_add(&w2, &w1, &w0, z[10]); + ws[10] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[10], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[11]); + word3_muladd(&w2, &w1, &w0, ws[1], p[10]); + word3_muladd(&w2, &w1, &w0, ws[2], p[9]); + word3_muladd(&w2, &w1, &w0, ws[3], p[8]); + word3_muladd(&w2, &w1, &w0, ws[4], p[7]); + word3_muladd(&w2, &w1, &w0, ws[5], p[6]); + word3_muladd(&w2, &w1, &w0, ws[6], p[5]); + word3_muladd(&w2, &w1, &w0, ws[7], p[4]); + word3_muladd(&w2, &w1, &w0, ws[8], p[3]); + word3_muladd(&w2, &w1, &w0, ws[9], p[2]); + word3_muladd(&w2, &w1, &w0, ws[10], p[1]); + word3_add(&w2, &w1, &w0, z[11]); + ws[11] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[11], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[12]); + word3_muladd(&w2, &w1, &w0, ws[1], p[11]); + word3_muladd(&w2, &w1, &w0, ws[2], p[10]); + word3_muladd(&w2, &w1, &w0, ws[3], p[9]); + word3_muladd(&w2, &w1, &w0, ws[4], p[8]); + word3_muladd(&w2, &w1, &w0, ws[5], p[7]); + word3_muladd(&w2, &w1, &w0, ws[6], p[6]); + word3_muladd(&w2, &w1, &w0, ws[7], p[5]); + word3_muladd(&w2, &w1, &w0, ws[8], p[4]); + word3_muladd(&w2, &w1, &w0, ws[9], p[3]); + word3_muladd(&w2, &w1, &w0, ws[10], p[2]); + word3_muladd(&w2, &w1, &w0, ws[11], p[1]); + word3_add(&w2, &w1, &w0, z[12]); + ws[12] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[12], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[13]); + word3_muladd(&w2, &w1, &w0, ws[1], p[12]); + word3_muladd(&w2, &w1, &w0, ws[2], p[11]); + word3_muladd(&w2, &w1, &w0, ws[3], p[10]); + word3_muladd(&w2, &w1, &w0, ws[4], p[9]); + word3_muladd(&w2, &w1, &w0, ws[5], p[8]); + word3_muladd(&w2, &w1, &w0, ws[6], p[7]); + word3_muladd(&w2, &w1, &w0, ws[7], p[6]); + word3_muladd(&w2, &w1, &w0, ws[8], p[5]); + word3_muladd(&w2, &w1, &w0, ws[9], p[4]); + word3_muladd(&w2, &w1, &w0, ws[10], p[3]); + word3_muladd(&w2, &w1, &w0, ws[11], p[2]); + word3_muladd(&w2, &w1, &w0, ws[12], p[1]); + word3_add(&w2, &w1, &w0, z[13]); + ws[13] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[13], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[14]); + word3_muladd(&w2, &w1, &w0, ws[1], p[13]); + word3_muladd(&w2, &w1, &w0, ws[2], p[12]); + word3_muladd(&w2, &w1, &w0, ws[3], p[11]); + word3_muladd(&w2, &w1, &w0, ws[4], p[10]); + word3_muladd(&w2, &w1, &w0, ws[5], p[9]); + word3_muladd(&w2, &w1, &w0, ws[6], p[8]); + word3_muladd(&w2, &w1, &w0, ws[7], p[7]); + word3_muladd(&w2, &w1, &w0, ws[8], p[6]); + word3_muladd(&w2, &w1, &w0, ws[9], p[5]); + word3_muladd(&w2, &w1, &w0, ws[10], p[4]); + word3_muladd(&w2, &w1, &w0, ws[11], p[3]); + word3_muladd(&w2, &w1, &w0, ws[12], p[2]); + word3_muladd(&w2, &w1, &w0, ws[13], p[1]); + word3_add(&w2, &w1, &w0, z[14]); + ws[14] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[14], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[15]); + word3_muladd(&w2, &w1, &w0, ws[1], p[14]); + word3_muladd(&w2, &w1, &w0, ws[2], p[13]); + word3_muladd(&w2, &w1, &w0, ws[3], p[12]); + word3_muladd(&w2, &w1, &w0, ws[4], p[11]); + word3_muladd(&w2, &w1, &w0, ws[5], p[10]); + word3_muladd(&w2, &w1, &w0, ws[6], p[9]); + word3_muladd(&w2, &w1, &w0, ws[7], p[8]); + word3_muladd(&w2, &w1, &w0, ws[8], p[7]); + word3_muladd(&w2, &w1, &w0, ws[9], p[6]); + word3_muladd(&w2, &w1, &w0, ws[10], p[5]); + word3_muladd(&w2, &w1, &w0, ws[11], p[4]); + word3_muladd(&w2, &w1, &w0, ws[12], p[3]); + word3_muladd(&w2, &w1, &w0, ws[13], p[2]); + word3_muladd(&w2, &w1, &w0, ws[14], p[1]); + word3_add(&w2, &w1, &w0, z[15]); + ws[15] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[15], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[15]); + word3_muladd(&w2, &w1, &w0, ws[2], p[14]); + word3_muladd(&w2, &w1, &w0, ws[3], p[13]); + word3_muladd(&w2, &w1, &w0, ws[4], p[12]); + word3_muladd(&w2, &w1, &w0, ws[5], p[11]); + word3_muladd(&w2, &w1, &w0, ws[6], p[10]); + word3_muladd(&w2, &w1, &w0, ws[7], p[9]); + word3_muladd(&w2, &w1, &w0, ws[8], p[8]); + word3_muladd(&w2, &w1, &w0, ws[9], p[7]); + word3_muladd(&w2, &w1, &w0, ws[10], p[6]); + word3_muladd(&w2, &w1, &w0, ws[11], p[5]); + word3_muladd(&w2, &w1, &w0, ws[12], p[4]); + word3_muladd(&w2, &w1, &w0, ws[13], p[3]); + word3_muladd(&w2, &w1, &w0, ws[14], p[2]); + word3_muladd(&w2, &w1, &w0, ws[15], p[1]); + word3_add(&w2, &w1, &w0, z[16]); + ws[0] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[15]); + word3_muladd(&w2, &w1, &w0, ws[3], p[14]); + word3_muladd(&w2, &w1, &w0, ws[4], p[13]); + word3_muladd(&w2, &w1, &w0, ws[5], p[12]); + word3_muladd(&w2, &w1, &w0, ws[6], p[11]); + word3_muladd(&w2, &w1, &w0, ws[7], p[10]); + word3_muladd(&w2, &w1, &w0, ws[8], p[9]); + word3_muladd(&w2, &w1, &w0, ws[9], p[8]); + word3_muladd(&w2, &w1, &w0, ws[10], p[7]); + word3_muladd(&w2, &w1, &w0, ws[11], p[6]); + word3_muladd(&w2, &w1, &w0, ws[12], p[5]); + word3_muladd(&w2, &w1, &w0, ws[13], p[4]); + word3_muladd(&w2, &w1, &w0, ws[14], p[3]); + word3_muladd(&w2, &w1, &w0, ws[15], p[2]); + word3_add(&w2, &w1, &w0, z[17]); + ws[1] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[15]); + word3_muladd(&w2, &w1, &w0, ws[4], p[14]); + word3_muladd(&w2, &w1, &w0, ws[5], p[13]); + word3_muladd(&w2, &w1, &w0, ws[6], p[12]); + word3_muladd(&w2, &w1, &w0, ws[7], p[11]); + word3_muladd(&w2, &w1, &w0, ws[8], p[10]); + word3_muladd(&w2, &w1, &w0, ws[9], p[9]); + word3_muladd(&w2, &w1, &w0, ws[10], p[8]); + word3_muladd(&w2, &w1, &w0, ws[11], p[7]); + word3_muladd(&w2, &w1, &w0, ws[12], p[6]); + word3_muladd(&w2, &w1, &w0, ws[13], p[5]); + word3_muladd(&w2, &w1, &w0, ws[14], p[4]); + word3_muladd(&w2, &w1, &w0, ws[15], p[3]); + word3_add(&w2, &w1, &w0, z[18]); + ws[2] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[15]); + word3_muladd(&w2, &w1, &w0, ws[5], p[14]); + word3_muladd(&w2, &w1, &w0, ws[6], p[13]); + word3_muladd(&w2, &w1, &w0, ws[7], p[12]); + word3_muladd(&w2, &w1, &w0, ws[8], p[11]); + word3_muladd(&w2, &w1, &w0, ws[9], p[10]); + word3_muladd(&w2, &w1, &w0, ws[10], p[9]); + word3_muladd(&w2, &w1, &w0, ws[11], p[8]); + word3_muladd(&w2, &w1, &w0, ws[12], p[7]); + word3_muladd(&w2, &w1, &w0, ws[13], p[6]); + word3_muladd(&w2, &w1, &w0, ws[14], p[5]); + word3_muladd(&w2, &w1, &w0, ws[15], p[4]); + word3_add(&w2, &w1, &w0, z[19]); + ws[3] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[15]); + word3_muladd(&w2, &w1, &w0, ws[6], p[14]); + word3_muladd(&w2, &w1, &w0, ws[7], p[13]); + word3_muladd(&w2, &w1, &w0, ws[8], p[12]); + word3_muladd(&w2, &w1, &w0, ws[9], p[11]); + word3_muladd(&w2, &w1, &w0, ws[10], p[10]); + word3_muladd(&w2, &w1, &w0, ws[11], p[9]); + word3_muladd(&w2, &w1, &w0, ws[12], p[8]); + word3_muladd(&w2, &w1, &w0, ws[13], p[7]); + word3_muladd(&w2, &w1, &w0, ws[14], p[6]); + word3_muladd(&w2, &w1, &w0, ws[15], p[5]); + word3_add(&w2, &w1, &w0, z[20]); + ws[4] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[6], p[15]); + word3_muladd(&w2, &w1, &w0, ws[7], p[14]); + word3_muladd(&w2, &w1, &w0, ws[8], p[13]); + word3_muladd(&w2, &w1, &w0, ws[9], p[12]); + word3_muladd(&w2, &w1, &w0, ws[10], p[11]); + word3_muladd(&w2, &w1, &w0, ws[11], p[10]); + word3_muladd(&w2, &w1, &w0, ws[12], p[9]); + word3_muladd(&w2, &w1, &w0, ws[13], p[8]); + word3_muladd(&w2, &w1, &w0, ws[14], p[7]); + word3_muladd(&w2, &w1, &w0, ws[15], p[6]); + word3_add(&w2, &w1, &w0, z[21]); + ws[5] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[7], p[15]); + word3_muladd(&w2, &w1, &w0, ws[8], p[14]); + word3_muladd(&w2, &w1, &w0, ws[9], p[13]); + word3_muladd(&w2, &w1, &w0, ws[10], p[12]); + word3_muladd(&w2, &w1, &w0, ws[11], p[11]); + word3_muladd(&w2, &w1, &w0, ws[12], p[10]); + word3_muladd(&w2, &w1, &w0, ws[13], p[9]); + word3_muladd(&w2, &w1, &w0, ws[14], p[8]); + word3_muladd(&w2, &w1, &w0, ws[15], p[7]); + word3_add(&w2, &w1, &w0, z[22]); + ws[6] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[8], p[15]); + word3_muladd(&w2, &w1, &w0, ws[9], p[14]); + word3_muladd(&w2, &w1, &w0, ws[10], p[13]); + word3_muladd(&w2, &w1, &w0, ws[11], p[12]); + word3_muladd(&w2, &w1, &w0, ws[12], p[11]); + word3_muladd(&w2, &w1, &w0, ws[13], p[10]); + word3_muladd(&w2, &w1, &w0, ws[14], p[9]); + word3_muladd(&w2, &w1, &w0, ws[15], p[8]); + word3_add(&w2, &w1, &w0, z[23]); + ws[7] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[9], p[15]); + word3_muladd(&w2, &w1, &w0, ws[10], p[14]); + word3_muladd(&w2, &w1, &w0, ws[11], p[13]); + word3_muladd(&w2, &w1, &w0, ws[12], p[12]); + word3_muladd(&w2, &w1, &w0, ws[13], p[11]); + word3_muladd(&w2, &w1, &w0, ws[14], p[10]); + word3_muladd(&w2, &w1, &w0, ws[15], p[9]); + word3_add(&w2, &w1, &w0, z[24]); + ws[8] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[10], p[15]); + word3_muladd(&w2, &w1, &w0, ws[11], p[14]); + word3_muladd(&w2, &w1, &w0, ws[12], p[13]); + word3_muladd(&w2, &w1, &w0, ws[13], p[12]); + word3_muladd(&w2, &w1, &w0, ws[14], p[11]); + word3_muladd(&w2, &w1, &w0, ws[15], p[10]); + word3_add(&w2, &w1, &w0, z[25]); + ws[9] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[11], p[15]); + word3_muladd(&w2, &w1, &w0, ws[12], p[14]); + word3_muladd(&w2, &w1, &w0, ws[13], p[13]); + word3_muladd(&w2, &w1, &w0, ws[14], p[12]); + word3_muladd(&w2, &w1, &w0, ws[15], p[11]); + word3_add(&w2, &w1, &w0, z[26]); + ws[10] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[12], p[15]); + word3_muladd(&w2, &w1, &w0, ws[13], p[14]); + word3_muladd(&w2, &w1, &w0, ws[14], p[13]); + word3_muladd(&w2, &w1, &w0, ws[15], p[12]); + word3_add(&w2, &w1, &w0, z[27]); + ws[11] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[13], p[15]); + word3_muladd(&w2, &w1, &w0, ws[14], p[14]); + word3_muladd(&w2, &w1, &w0, ws[15], p[13]); + word3_add(&w2, &w1, &w0, z[28]); + ws[12] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[14], p[15]); + word3_muladd(&w2, &w1, &w0, ws[15], p[14]); + word3_add(&w2, &w1, &w0, z[29]); + ws[13] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[15], p[15]); + word3_add(&w2, &w1, &w0, z[30]); + ws[14] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[31]); + ws[15] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[33]); + ws[16] = w0; + ws[17] = w1; + word borrow = bigint_sub3(ws + 16 + 1, ws, 16 + 1, p, 16); + CT::conditional_copy_mem(borrow, z, ws, ws + 17, 17); + clear_mem(z + 16, 2 * (16 + 1) - 16); +} + +void bigint_monty_redc_24(word z[], const word p[24], word p_dash, word ws[]) { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[6]); + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[6] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[6], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[7]); + word3_muladd(&w2, &w1, &w0, ws[1], p[6]); + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_muladd(&w2, &w1, &w0, ws[6], p[1]); + word3_add(&w2, &w1, &w0, z[7]); + ws[7] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[7], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[8]); + word3_muladd(&w2, &w1, &w0, ws[1], p[7]); + word3_muladd(&w2, &w1, &w0, ws[2], p[6]); + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_muladd(&w2, &w1, &w0, ws[6], p[2]); + word3_muladd(&w2, &w1, &w0, ws[7], p[1]); + word3_add(&w2, &w1, &w0, z[8]); + ws[8] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[8], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[9]); + word3_muladd(&w2, &w1, &w0, ws[1], p[8]); + word3_muladd(&w2, &w1, &w0, ws[2], p[7]); + word3_muladd(&w2, &w1, &w0, ws[3], p[6]); + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_muladd(&w2, &w1, &w0, ws[6], p[3]); + word3_muladd(&w2, &w1, &w0, ws[7], p[2]); + word3_muladd(&w2, &w1, &w0, ws[8], p[1]); + word3_add(&w2, &w1, &w0, z[9]); + ws[9] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[9], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[10]); + word3_muladd(&w2, &w1, &w0, ws[1], p[9]); + word3_muladd(&w2, &w1, &w0, ws[2], p[8]); + word3_muladd(&w2, &w1, &w0, ws[3], p[7]); + word3_muladd(&w2, &w1, &w0, ws[4], p[6]); + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_muladd(&w2, &w1, &w0, ws[6], p[4]); + word3_muladd(&w2, &w1, &w0, ws[7], p[3]); + word3_muladd(&w2, &w1, &w0, ws[8], p[2]); + word3_muladd(&w2, &w1, &w0, ws[9], p[1]); + word3_add(&w2, &w1, &w0, z[10]); + ws[10] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[10], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[11]); + word3_muladd(&w2, &w1, &w0, ws[1], p[10]); + word3_muladd(&w2, &w1, &w0, ws[2], p[9]); + word3_muladd(&w2, &w1, &w0, ws[3], p[8]); + word3_muladd(&w2, &w1, &w0, ws[4], p[7]); + word3_muladd(&w2, &w1, &w0, ws[5], p[6]); + word3_muladd(&w2, &w1, &w0, ws[6], p[5]); + word3_muladd(&w2, &w1, &w0, ws[7], p[4]); + word3_muladd(&w2, &w1, &w0, ws[8], p[3]); + word3_muladd(&w2, &w1, &w0, ws[9], p[2]); + word3_muladd(&w2, &w1, &w0, ws[10], p[1]); + word3_add(&w2, &w1, &w0, z[11]); + ws[11] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[11], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[12]); + word3_muladd(&w2, &w1, &w0, ws[1], p[11]); + word3_muladd(&w2, &w1, &w0, ws[2], p[10]); + word3_muladd(&w2, &w1, &w0, ws[3], p[9]); + word3_muladd(&w2, &w1, &w0, ws[4], p[8]); + word3_muladd(&w2, &w1, &w0, ws[5], p[7]); + word3_muladd(&w2, &w1, &w0, ws[6], p[6]); + word3_muladd(&w2, &w1, &w0, ws[7], p[5]); + word3_muladd(&w2, &w1, &w0, ws[8], p[4]); + word3_muladd(&w2, &w1, &w0, ws[9], p[3]); + word3_muladd(&w2, &w1, &w0, ws[10], p[2]); + word3_muladd(&w2, &w1, &w0, ws[11], p[1]); + word3_add(&w2, &w1, &w0, z[12]); + ws[12] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[12], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[13]); + word3_muladd(&w2, &w1, &w0, ws[1], p[12]); + word3_muladd(&w2, &w1, &w0, ws[2], p[11]); + word3_muladd(&w2, &w1, &w0, ws[3], p[10]); + word3_muladd(&w2, &w1, &w0, ws[4], p[9]); + word3_muladd(&w2, &w1, &w0, ws[5], p[8]); + word3_muladd(&w2, &w1, &w0, ws[6], p[7]); + word3_muladd(&w2, &w1, &w0, ws[7], p[6]); + word3_muladd(&w2, &w1, &w0, ws[8], p[5]); + word3_muladd(&w2, &w1, &w0, ws[9], p[4]); + word3_muladd(&w2, &w1, &w0, ws[10], p[3]); + word3_muladd(&w2, &w1, &w0, ws[11], p[2]); + word3_muladd(&w2, &w1, &w0, ws[12], p[1]); + word3_add(&w2, &w1, &w0, z[13]); + ws[13] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[13], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[14]); + word3_muladd(&w2, &w1, &w0, ws[1], p[13]); + word3_muladd(&w2, &w1, &w0, ws[2], p[12]); + word3_muladd(&w2, &w1, &w0, ws[3], p[11]); + word3_muladd(&w2, &w1, &w0, ws[4], p[10]); + word3_muladd(&w2, &w1, &w0, ws[5], p[9]); + word3_muladd(&w2, &w1, &w0, ws[6], p[8]); + word3_muladd(&w2, &w1, &w0, ws[7], p[7]); + word3_muladd(&w2, &w1, &w0, ws[8], p[6]); + word3_muladd(&w2, &w1, &w0, ws[9], p[5]); + word3_muladd(&w2, &w1, &w0, ws[10], p[4]); + word3_muladd(&w2, &w1, &w0, ws[11], p[3]); + word3_muladd(&w2, &w1, &w0, ws[12], p[2]); + word3_muladd(&w2, &w1, &w0, ws[13], p[1]); + word3_add(&w2, &w1, &w0, z[14]); + ws[14] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[14], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[15]); + word3_muladd(&w2, &w1, &w0, ws[1], p[14]); + word3_muladd(&w2, &w1, &w0, ws[2], p[13]); + word3_muladd(&w2, &w1, &w0, ws[3], p[12]); + word3_muladd(&w2, &w1, &w0, ws[4], p[11]); + word3_muladd(&w2, &w1, &w0, ws[5], p[10]); + word3_muladd(&w2, &w1, &w0, ws[6], p[9]); + word3_muladd(&w2, &w1, &w0, ws[7], p[8]); + word3_muladd(&w2, &w1, &w0, ws[8], p[7]); + word3_muladd(&w2, &w1, &w0, ws[9], p[6]); + word3_muladd(&w2, &w1, &w0, ws[10], p[5]); + word3_muladd(&w2, &w1, &w0, ws[11], p[4]); + word3_muladd(&w2, &w1, &w0, ws[12], p[3]); + word3_muladd(&w2, &w1, &w0, ws[13], p[2]); + word3_muladd(&w2, &w1, &w0, ws[14], p[1]); + word3_add(&w2, &w1, &w0, z[15]); + ws[15] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[15], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[16]); + word3_muladd(&w2, &w1, &w0, ws[1], p[15]); + word3_muladd(&w2, &w1, &w0, ws[2], p[14]); + word3_muladd(&w2, &w1, &w0, ws[3], p[13]); + word3_muladd(&w2, &w1, &w0, ws[4], p[12]); + word3_muladd(&w2, &w1, &w0, ws[5], p[11]); + word3_muladd(&w2, &w1, &w0, ws[6], p[10]); + word3_muladd(&w2, &w1, &w0, ws[7], p[9]); + word3_muladd(&w2, &w1, &w0, ws[8], p[8]); + word3_muladd(&w2, &w1, &w0, ws[9], p[7]); + word3_muladd(&w2, &w1, &w0, ws[10], p[6]); + word3_muladd(&w2, &w1, &w0, ws[11], p[5]); + word3_muladd(&w2, &w1, &w0, ws[12], p[4]); + word3_muladd(&w2, &w1, &w0, ws[13], p[3]); + word3_muladd(&w2, &w1, &w0, ws[14], p[2]); + word3_muladd(&w2, &w1, &w0, ws[15], p[1]); + word3_add(&w2, &w1, &w0, z[16]); + ws[16] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[16], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[17]); + word3_muladd(&w2, &w1, &w0, ws[1], p[16]); + word3_muladd(&w2, &w1, &w0, ws[2], p[15]); + word3_muladd(&w2, &w1, &w0, ws[3], p[14]); + word3_muladd(&w2, &w1, &w0, ws[4], p[13]); + word3_muladd(&w2, &w1, &w0, ws[5], p[12]); + word3_muladd(&w2, &w1, &w0, ws[6], p[11]); + word3_muladd(&w2, &w1, &w0, ws[7], p[10]); + word3_muladd(&w2, &w1, &w0, ws[8], p[9]); + word3_muladd(&w2, &w1, &w0, ws[9], p[8]); + word3_muladd(&w2, &w1, &w0, ws[10], p[7]); + word3_muladd(&w2, &w1, &w0, ws[11], p[6]); + word3_muladd(&w2, &w1, &w0, ws[12], p[5]); + word3_muladd(&w2, &w1, &w0, ws[13], p[4]); + word3_muladd(&w2, &w1, &w0, ws[14], p[3]); + word3_muladd(&w2, &w1, &w0, ws[15], p[2]); + word3_muladd(&w2, &w1, &w0, ws[16], p[1]); + word3_add(&w2, &w1, &w0, z[17]); + ws[17] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[17], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[18]); + word3_muladd(&w2, &w1, &w0, ws[1], p[17]); + word3_muladd(&w2, &w1, &w0, ws[2], p[16]); + word3_muladd(&w2, &w1, &w0, ws[3], p[15]); + word3_muladd(&w2, &w1, &w0, ws[4], p[14]); + word3_muladd(&w2, &w1, &w0, ws[5], p[13]); + word3_muladd(&w2, &w1, &w0, ws[6], p[12]); + word3_muladd(&w2, &w1, &w0, ws[7], p[11]); + word3_muladd(&w2, &w1, &w0, ws[8], p[10]); + word3_muladd(&w2, &w1, &w0, ws[9], p[9]); + word3_muladd(&w2, &w1, &w0, ws[10], p[8]); + word3_muladd(&w2, &w1, &w0, ws[11], p[7]); + word3_muladd(&w2, &w1, &w0, ws[12], p[6]); + word3_muladd(&w2, &w1, &w0, ws[13], p[5]); + word3_muladd(&w2, &w1, &w0, ws[14], p[4]); + word3_muladd(&w2, &w1, &w0, ws[15], p[3]); + word3_muladd(&w2, &w1, &w0, ws[16], p[2]); + word3_muladd(&w2, &w1, &w0, ws[17], p[1]); + word3_add(&w2, &w1, &w0, z[18]); + ws[18] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[18], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[19]); + word3_muladd(&w2, &w1, &w0, ws[1], p[18]); + word3_muladd(&w2, &w1, &w0, ws[2], p[17]); + word3_muladd(&w2, &w1, &w0, ws[3], p[16]); + word3_muladd(&w2, &w1, &w0, ws[4], p[15]); + word3_muladd(&w2, &w1, &w0, ws[5], p[14]); + word3_muladd(&w2, &w1, &w0, ws[6], p[13]); + word3_muladd(&w2, &w1, &w0, ws[7], p[12]); + word3_muladd(&w2, &w1, &w0, ws[8], p[11]); + word3_muladd(&w2, &w1, &w0, ws[9], p[10]); + word3_muladd(&w2, &w1, &w0, ws[10], p[9]); + word3_muladd(&w2, &w1, &w0, ws[11], p[8]); + word3_muladd(&w2, &w1, &w0, ws[12], p[7]); + word3_muladd(&w2, &w1, &w0, ws[13], p[6]); + word3_muladd(&w2, &w1, &w0, ws[14], p[5]); + word3_muladd(&w2, &w1, &w0, ws[15], p[4]); + word3_muladd(&w2, &w1, &w0, ws[16], p[3]); + word3_muladd(&w2, &w1, &w0, ws[17], p[2]); + word3_muladd(&w2, &w1, &w0, ws[18], p[1]); + word3_add(&w2, &w1, &w0, z[19]); + ws[19] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[19], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[20]); + word3_muladd(&w2, &w1, &w0, ws[1], p[19]); + word3_muladd(&w2, &w1, &w0, ws[2], p[18]); + word3_muladd(&w2, &w1, &w0, ws[3], p[17]); + word3_muladd(&w2, &w1, &w0, ws[4], p[16]); + word3_muladd(&w2, &w1, &w0, ws[5], p[15]); + word3_muladd(&w2, &w1, &w0, ws[6], p[14]); + word3_muladd(&w2, &w1, &w0, ws[7], p[13]); + word3_muladd(&w2, &w1, &w0, ws[8], p[12]); + word3_muladd(&w2, &w1, &w0, ws[9], p[11]); + word3_muladd(&w2, &w1, &w0, ws[10], p[10]); + word3_muladd(&w2, &w1, &w0, ws[11], p[9]); + word3_muladd(&w2, &w1, &w0, ws[12], p[8]); + word3_muladd(&w2, &w1, &w0, ws[13], p[7]); + word3_muladd(&w2, &w1, &w0, ws[14], p[6]); + word3_muladd(&w2, &w1, &w0, ws[15], p[5]); + word3_muladd(&w2, &w1, &w0, ws[16], p[4]); + word3_muladd(&w2, &w1, &w0, ws[17], p[3]); + word3_muladd(&w2, &w1, &w0, ws[18], p[2]); + word3_muladd(&w2, &w1, &w0, ws[19], p[1]); + word3_add(&w2, &w1, &w0, z[20]); + ws[20] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[20], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[21]); + word3_muladd(&w2, &w1, &w0, ws[1], p[20]); + word3_muladd(&w2, &w1, &w0, ws[2], p[19]); + word3_muladd(&w2, &w1, &w0, ws[3], p[18]); + word3_muladd(&w2, &w1, &w0, ws[4], p[17]); + word3_muladd(&w2, &w1, &w0, ws[5], p[16]); + word3_muladd(&w2, &w1, &w0, ws[6], p[15]); + word3_muladd(&w2, &w1, &w0, ws[7], p[14]); + word3_muladd(&w2, &w1, &w0, ws[8], p[13]); + word3_muladd(&w2, &w1, &w0, ws[9], p[12]); + word3_muladd(&w2, &w1, &w0, ws[10], p[11]); + word3_muladd(&w2, &w1, &w0, ws[11], p[10]); + word3_muladd(&w2, &w1, &w0, ws[12], p[9]); + word3_muladd(&w2, &w1, &w0, ws[13], p[8]); + word3_muladd(&w2, &w1, &w0, ws[14], p[7]); + word3_muladd(&w2, &w1, &w0, ws[15], p[6]); + word3_muladd(&w2, &w1, &w0, ws[16], p[5]); + word3_muladd(&w2, &w1, &w0, ws[17], p[4]); + word3_muladd(&w2, &w1, &w0, ws[18], p[3]); + word3_muladd(&w2, &w1, &w0, ws[19], p[2]); + word3_muladd(&w2, &w1, &w0, ws[20], p[1]); + word3_add(&w2, &w1, &w0, z[21]); + ws[21] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[21], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[22]); + word3_muladd(&w2, &w1, &w0, ws[1], p[21]); + word3_muladd(&w2, &w1, &w0, ws[2], p[20]); + word3_muladd(&w2, &w1, &w0, ws[3], p[19]); + word3_muladd(&w2, &w1, &w0, ws[4], p[18]); + word3_muladd(&w2, &w1, &w0, ws[5], p[17]); + word3_muladd(&w2, &w1, &w0, ws[6], p[16]); + word3_muladd(&w2, &w1, &w0, ws[7], p[15]); + word3_muladd(&w2, &w1, &w0, ws[8], p[14]); + word3_muladd(&w2, &w1, &w0, ws[9], p[13]); + word3_muladd(&w2, &w1, &w0, ws[10], p[12]); + word3_muladd(&w2, &w1, &w0, ws[11], p[11]); + word3_muladd(&w2, &w1, &w0, ws[12], p[10]); + word3_muladd(&w2, &w1, &w0, ws[13], p[9]); + word3_muladd(&w2, &w1, &w0, ws[14], p[8]); + word3_muladd(&w2, &w1, &w0, ws[15], p[7]); + word3_muladd(&w2, &w1, &w0, ws[16], p[6]); + word3_muladd(&w2, &w1, &w0, ws[17], p[5]); + word3_muladd(&w2, &w1, &w0, ws[18], p[4]); + word3_muladd(&w2, &w1, &w0, ws[19], p[3]); + word3_muladd(&w2, &w1, &w0, ws[20], p[2]); + word3_muladd(&w2, &w1, &w0, ws[21], p[1]); + word3_add(&w2, &w1, &w0, z[22]); + ws[22] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[22], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[23]); + word3_muladd(&w2, &w1, &w0, ws[1], p[22]); + word3_muladd(&w2, &w1, &w0, ws[2], p[21]); + word3_muladd(&w2, &w1, &w0, ws[3], p[20]); + word3_muladd(&w2, &w1, &w0, ws[4], p[19]); + word3_muladd(&w2, &w1, &w0, ws[5], p[18]); + word3_muladd(&w2, &w1, &w0, ws[6], p[17]); + word3_muladd(&w2, &w1, &w0, ws[7], p[16]); + word3_muladd(&w2, &w1, &w0, ws[8], p[15]); + word3_muladd(&w2, &w1, &w0, ws[9], p[14]); + word3_muladd(&w2, &w1, &w0, ws[10], p[13]); + word3_muladd(&w2, &w1, &w0, ws[11], p[12]); + word3_muladd(&w2, &w1, &w0, ws[12], p[11]); + word3_muladd(&w2, &w1, &w0, ws[13], p[10]); + word3_muladd(&w2, &w1, &w0, ws[14], p[9]); + word3_muladd(&w2, &w1, &w0, ws[15], p[8]); + word3_muladd(&w2, &w1, &w0, ws[16], p[7]); + word3_muladd(&w2, &w1, &w0, ws[17], p[6]); + word3_muladd(&w2, &w1, &w0, ws[18], p[5]); + word3_muladd(&w2, &w1, &w0, ws[19], p[4]); + word3_muladd(&w2, &w1, &w0, ws[20], p[3]); + word3_muladd(&w2, &w1, &w0, ws[21], p[2]); + word3_muladd(&w2, &w1, &w0, ws[22], p[1]); + word3_add(&w2, &w1, &w0, z[23]); + ws[23] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[23], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[23]); + word3_muladd(&w2, &w1, &w0, ws[2], p[22]); + word3_muladd(&w2, &w1, &w0, ws[3], p[21]); + word3_muladd(&w2, &w1, &w0, ws[4], p[20]); + word3_muladd(&w2, &w1, &w0, ws[5], p[19]); + word3_muladd(&w2, &w1, &w0, ws[6], p[18]); + word3_muladd(&w2, &w1, &w0, ws[7], p[17]); + word3_muladd(&w2, &w1, &w0, ws[8], p[16]); + word3_muladd(&w2, &w1, &w0, ws[9], p[15]); + word3_muladd(&w2, &w1, &w0, ws[10], p[14]); + word3_muladd(&w2, &w1, &w0, ws[11], p[13]); + word3_muladd(&w2, &w1, &w0, ws[12], p[12]); + word3_muladd(&w2, &w1, &w0, ws[13], p[11]); + word3_muladd(&w2, &w1, &w0, ws[14], p[10]); + word3_muladd(&w2, &w1, &w0, ws[15], p[9]); + word3_muladd(&w2, &w1, &w0, ws[16], p[8]); + word3_muladd(&w2, &w1, &w0, ws[17], p[7]); + word3_muladd(&w2, &w1, &w0, ws[18], p[6]); + word3_muladd(&w2, &w1, &w0, ws[19], p[5]); + word3_muladd(&w2, &w1, &w0, ws[20], p[4]); + word3_muladd(&w2, &w1, &w0, ws[21], p[3]); + word3_muladd(&w2, &w1, &w0, ws[22], p[2]); + word3_muladd(&w2, &w1, &w0, ws[23], p[1]); + word3_add(&w2, &w1, &w0, z[24]); + ws[0] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[23]); + word3_muladd(&w2, &w1, &w0, ws[3], p[22]); + word3_muladd(&w2, &w1, &w0, ws[4], p[21]); + word3_muladd(&w2, &w1, &w0, ws[5], p[20]); + word3_muladd(&w2, &w1, &w0, ws[6], p[19]); + word3_muladd(&w2, &w1, &w0, ws[7], p[18]); + word3_muladd(&w2, &w1, &w0, ws[8], p[17]); + word3_muladd(&w2, &w1, &w0, ws[9], p[16]); + word3_muladd(&w2, &w1, &w0, ws[10], p[15]); + word3_muladd(&w2, &w1, &w0, ws[11], p[14]); + word3_muladd(&w2, &w1, &w0, ws[12], p[13]); + word3_muladd(&w2, &w1, &w0, ws[13], p[12]); + word3_muladd(&w2, &w1, &w0, ws[14], p[11]); + word3_muladd(&w2, &w1, &w0, ws[15], p[10]); + word3_muladd(&w2, &w1, &w0, ws[16], p[9]); + word3_muladd(&w2, &w1, &w0, ws[17], p[8]); + word3_muladd(&w2, &w1, &w0, ws[18], p[7]); + word3_muladd(&w2, &w1, &w0, ws[19], p[6]); + word3_muladd(&w2, &w1, &w0, ws[20], p[5]); + word3_muladd(&w2, &w1, &w0, ws[21], p[4]); + word3_muladd(&w2, &w1, &w0, ws[22], p[3]); + word3_muladd(&w2, &w1, &w0, ws[23], p[2]); + word3_add(&w2, &w1, &w0, z[25]); + ws[1] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[23]); + word3_muladd(&w2, &w1, &w0, ws[4], p[22]); + word3_muladd(&w2, &w1, &w0, ws[5], p[21]); + word3_muladd(&w2, &w1, &w0, ws[6], p[20]); + word3_muladd(&w2, &w1, &w0, ws[7], p[19]); + word3_muladd(&w2, &w1, &w0, ws[8], p[18]); + word3_muladd(&w2, &w1, &w0, ws[9], p[17]); + word3_muladd(&w2, &w1, &w0, ws[10], p[16]); + word3_muladd(&w2, &w1, &w0, ws[11], p[15]); + word3_muladd(&w2, &w1, &w0, ws[12], p[14]); + word3_muladd(&w2, &w1, &w0, ws[13], p[13]); + word3_muladd(&w2, &w1, &w0, ws[14], p[12]); + word3_muladd(&w2, &w1, &w0, ws[15], p[11]); + word3_muladd(&w2, &w1, &w0, ws[16], p[10]); + word3_muladd(&w2, &w1, &w0, ws[17], p[9]); + word3_muladd(&w2, &w1, &w0, ws[18], p[8]); + word3_muladd(&w2, &w1, &w0, ws[19], p[7]); + word3_muladd(&w2, &w1, &w0, ws[20], p[6]); + word3_muladd(&w2, &w1, &w0, ws[21], p[5]); + word3_muladd(&w2, &w1, &w0, ws[22], p[4]); + word3_muladd(&w2, &w1, &w0, ws[23], p[3]); + word3_add(&w2, &w1, &w0, z[26]); + ws[2] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[23]); + word3_muladd(&w2, &w1, &w0, ws[5], p[22]); + word3_muladd(&w2, &w1, &w0, ws[6], p[21]); + word3_muladd(&w2, &w1, &w0, ws[7], p[20]); + word3_muladd(&w2, &w1, &w0, ws[8], p[19]); + word3_muladd(&w2, &w1, &w0, ws[9], p[18]); + word3_muladd(&w2, &w1, &w0, ws[10], p[17]); + word3_muladd(&w2, &w1, &w0, ws[11], p[16]); + word3_muladd(&w2, &w1, &w0, ws[12], p[15]); + word3_muladd(&w2, &w1, &w0, ws[13], p[14]); + word3_muladd(&w2, &w1, &w0, ws[14], p[13]); + word3_muladd(&w2, &w1, &w0, ws[15], p[12]); + word3_muladd(&w2, &w1, &w0, ws[16], p[11]); + word3_muladd(&w2, &w1, &w0, ws[17], p[10]); + word3_muladd(&w2, &w1, &w0, ws[18], p[9]); + word3_muladd(&w2, &w1, &w0, ws[19], p[8]); + word3_muladd(&w2, &w1, &w0, ws[20], p[7]); + word3_muladd(&w2, &w1, &w0, ws[21], p[6]); + word3_muladd(&w2, &w1, &w0, ws[22], p[5]); + word3_muladd(&w2, &w1, &w0, ws[23], p[4]); + word3_add(&w2, &w1, &w0, z[27]); + ws[3] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[23]); + word3_muladd(&w2, &w1, &w0, ws[6], p[22]); + word3_muladd(&w2, &w1, &w0, ws[7], p[21]); + word3_muladd(&w2, &w1, &w0, ws[8], p[20]); + word3_muladd(&w2, &w1, &w0, ws[9], p[19]); + word3_muladd(&w2, &w1, &w0, ws[10], p[18]); + word3_muladd(&w2, &w1, &w0, ws[11], p[17]); + word3_muladd(&w2, &w1, &w0, ws[12], p[16]); + word3_muladd(&w2, &w1, &w0, ws[13], p[15]); + word3_muladd(&w2, &w1, &w0, ws[14], p[14]); + word3_muladd(&w2, &w1, &w0, ws[15], p[13]); + word3_muladd(&w2, &w1, &w0, ws[16], p[12]); + word3_muladd(&w2, &w1, &w0, ws[17], p[11]); + word3_muladd(&w2, &w1, &w0, ws[18], p[10]); + word3_muladd(&w2, &w1, &w0, ws[19], p[9]); + word3_muladd(&w2, &w1, &w0, ws[20], p[8]); + word3_muladd(&w2, &w1, &w0, ws[21], p[7]); + word3_muladd(&w2, &w1, &w0, ws[22], p[6]); + word3_muladd(&w2, &w1, &w0, ws[23], p[5]); + word3_add(&w2, &w1, &w0, z[28]); + ws[4] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[6], p[23]); + word3_muladd(&w2, &w1, &w0, ws[7], p[22]); + word3_muladd(&w2, &w1, &w0, ws[8], p[21]); + word3_muladd(&w2, &w1, &w0, ws[9], p[20]); + word3_muladd(&w2, &w1, &w0, ws[10], p[19]); + word3_muladd(&w2, &w1, &w0, ws[11], p[18]); + word3_muladd(&w2, &w1, &w0, ws[12], p[17]); + word3_muladd(&w2, &w1, &w0, ws[13], p[16]); + word3_muladd(&w2, &w1, &w0, ws[14], p[15]); + word3_muladd(&w2, &w1, &w0, ws[15], p[14]); + word3_muladd(&w2, &w1, &w0, ws[16], p[13]); + word3_muladd(&w2, &w1, &w0, ws[17], p[12]); + word3_muladd(&w2, &w1, &w0, ws[18], p[11]); + word3_muladd(&w2, &w1, &w0, ws[19], p[10]); + word3_muladd(&w2, &w1, &w0, ws[20], p[9]); + word3_muladd(&w2, &w1, &w0, ws[21], p[8]); + word3_muladd(&w2, &w1, &w0, ws[22], p[7]); + word3_muladd(&w2, &w1, &w0, ws[23], p[6]); + word3_add(&w2, &w1, &w0, z[29]); + ws[5] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[7], p[23]); + word3_muladd(&w2, &w1, &w0, ws[8], p[22]); + word3_muladd(&w2, &w1, &w0, ws[9], p[21]); + word3_muladd(&w2, &w1, &w0, ws[10], p[20]); + word3_muladd(&w2, &w1, &w0, ws[11], p[19]); + word3_muladd(&w2, &w1, &w0, ws[12], p[18]); + word3_muladd(&w2, &w1, &w0, ws[13], p[17]); + word3_muladd(&w2, &w1, &w0, ws[14], p[16]); + word3_muladd(&w2, &w1, &w0, ws[15], p[15]); + word3_muladd(&w2, &w1, &w0, ws[16], p[14]); + word3_muladd(&w2, &w1, &w0, ws[17], p[13]); + word3_muladd(&w2, &w1, &w0, ws[18], p[12]); + word3_muladd(&w2, &w1, &w0, ws[19], p[11]); + word3_muladd(&w2, &w1, &w0, ws[20], p[10]); + word3_muladd(&w2, &w1, &w0, ws[21], p[9]); + word3_muladd(&w2, &w1, &w0, ws[22], p[8]); + word3_muladd(&w2, &w1, &w0, ws[23], p[7]); + word3_add(&w2, &w1, &w0, z[30]); + ws[6] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[8], p[23]); + word3_muladd(&w2, &w1, &w0, ws[9], p[22]); + word3_muladd(&w2, &w1, &w0, ws[10], p[21]); + word3_muladd(&w2, &w1, &w0, ws[11], p[20]); + word3_muladd(&w2, &w1, &w0, ws[12], p[19]); + word3_muladd(&w2, &w1, &w0, ws[13], p[18]); + word3_muladd(&w2, &w1, &w0, ws[14], p[17]); + word3_muladd(&w2, &w1, &w0, ws[15], p[16]); + word3_muladd(&w2, &w1, &w0, ws[16], p[15]); + word3_muladd(&w2, &w1, &w0, ws[17], p[14]); + word3_muladd(&w2, &w1, &w0, ws[18], p[13]); + word3_muladd(&w2, &w1, &w0, ws[19], p[12]); + word3_muladd(&w2, &w1, &w0, ws[20], p[11]); + word3_muladd(&w2, &w1, &w0, ws[21], p[10]); + word3_muladd(&w2, &w1, &w0, ws[22], p[9]); + word3_muladd(&w2, &w1, &w0, ws[23], p[8]); + word3_add(&w2, &w1, &w0, z[31]); + ws[7] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[9], p[23]); + word3_muladd(&w2, &w1, &w0, ws[10], p[22]); + word3_muladd(&w2, &w1, &w0, ws[11], p[21]); + word3_muladd(&w2, &w1, &w0, ws[12], p[20]); + word3_muladd(&w2, &w1, &w0, ws[13], p[19]); + word3_muladd(&w2, &w1, &w0, ws[14], p[18]); + word3_muladd(&w2, &w1, &w0, ws[15], p[17]); + word3_muladd(&w2, &w1, &w0, ws[16], p[16]); + word3_muladd(&w2, &w1, &w0, ws[17], p[15]); + word3_muladd(&w2, &w1, &w0, ws[18], p[14]); + word3_muladd(&w2, &w1, &w0, ws[19], p[13]); + word3_muladd(&w2, &w1, &w0, ws[20], p[12]); + word3_muladd(&w2, &w1, &w0, ws[21], p[11]); + word3_muladd(&w2, &w1, &w0, ws[22], p[10]); + word3_muladd(&w2, &w1, &w0, ws[23], p[9]); + word3_add(&w2, &w1, &w0, z[32]); + ws[8] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[10], p[23]); + word3_muladd(&w2, &w1, &w0, ws[11], p[22]); + word3_muladd(&w2, &w1, &w0, ws[12], p[21]); + word3_muladd(&w2, &w1, &w0, ws[13], p[20]); + word3_muladd(&w2, &w1, &w0, ws[14], p[19]); + word3_muladd(&w2, &w1, &w0, ws[15], p[18]); + word3_muladd(&w2, &w1, &w0, ws[16], p[17]); + word3_muladd(&w2, &w1, &w0, ws[17], p[16]); + word3_muladd(&w2, &w1, &w0, ws[18], p[15]); + word3_muladd(&w2, &w1, &w0, ws[19], p[14]); + word3_muladd(&w2, &w1, &w0, ws[20], p[13]); + word3_muladd(&w2, &w1, &w0, ws[21], p[12]); + word3_muladd(&w2, &w1, &w0, ws[22], p[11]); + word3_muladd(&w2, &w1, &w0, ws[23], p[10]); + word3_add(&w2, &w1, &w0, z[33]); + ws[9] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[11], p[23]); + word3_muladd(&w2, &w1, &w0, ws[12], p[22]); + word3_muladd(&w2, &w1, &w0, ws[13], p[21]); + word3_muladd(&w2, &w1, &w0, ws[14], p[20]); + word3_muladd(&w2, &w1, &w0, ws[15], p[19]); + word3_muladd(&w2, &w1, &w0, ws[16], p[18]); + word3_muladd(&w2, &w1, &w0, ws[17], p[17]); + word3_muladd(&w2, &w1, &w0, ws[18], p[16]); + word3_muladd(&w2, &w1, &w0, ws[19], p[15]); + word3_muladd(&w2, &w1, &w0, ws[20], p[14]); + word3_muladd(&w2, &w1, &w0, ws[21], p[13]); + word3_muladd(&w2, &w1, &w0, ws[22], p[12]); + word3_muladd(&w2, &w1, &w0, ws[23], p[11]); + word3_add(&w2, &w1, &w0, z[34]); + ws[10] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[12], p[23]); + word3_muladd(&w2, &w1, &w0, ws[13], p[22]); + word3_muladd(&w2, &w1, &w0, ws[14], p[21]); + word3_muladd(&w2, &w1, &w0, ws[15], p[20]); + word3_muladd(&w2, &w1, &w0, ws[16], p[19]); + word3_muladd(&w2, &w1, &w0, ws[17], p[18]); + word3_muladd(&w2, &w1, &w0, ws[18], p[17]); + word3_muladd(&w2, &w1, &w0, ws[19], p[16]); + word3_muladd(&w2, &w1, &w0, ws[20], p[15]); + word3_muladd(&w2, &w1, &w0, ws[21], p[14]); + word3_muladd(&w2, &w1, &w0, ws[22], p[13]); + word3_muladd(&w2, &w1, &w0, ws[23], p[12]); + word3_add(&w2, &w1, &w0, z[35]); + ws[11] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[13], p[23]); + word3_muladd(&w2, &w1, &w0, ws[14], p[22]); + word3_muladd(&w2, &w1, &w0, ws[15], p[21]); + word3_muladd(&w2, &w1, &w0, ws[16], p[20]); + word3_muladd(&w2, &w1, &w0, ws[17], p[19]); + word3_muladd(&w2, &w1, &w0, ws[18], p[18]); + word3_muladd(&w2, &w1, &w0, ws[19], p[17]); + word3_muladd(&w2, &w1, &w0, ws[20], p[16]); + word3_muladd(&w2, &w1, &w0, ws[21], p[15]); + word3_muladd(&w2, &w1, &w0, ws[22], p[14]); + word3_muladd(&w2, &w1, &w0, ws[23], p[13]); + word3_add(&w2, &w1, &w0, z[36]); + ws[12] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[14], p[23]); + word3_muladd(&w2, &w1, &w0, ws[15], p[22]); + word3_muladd(&w2, &w1, &w0, ws[16], p[21]); + word3_muladd(&w2, &w1, &w0, ws[17], p[20]); + word3_muladd(&w2, &w1, &w0, ws[18], p[19]); + word3_muladd(&w2, &w1, &w0, ws[19], p[18]); + word3_muladd(&w2, &w1, &w0, ws[20], p[17]); + word3_muladd(&w2, &w1, &w0, ws[21], p[16]); + word3_muladd(&w2, &w1, &w0, ws[22], p[15]); + word3_muladd(&w2, &w1, &w0, ws[23], p[14]); + word3_add(&w2, &w1, &w0, z[37]); + ws[13] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[15], p[23]); + word3_muladd(&w2, &w1, &w0, ws[16], p[22]); + word3_muladd(&w2, &w1, &w0, ws[17], p[21]); + word3_muladd(&w2, &w1, &w0, ws[18], p[20]); + word3_muladd(&w2, &w1, &w0, ws[19], p[19]); + word3_muladd(&w2, &w1, &w0, ws[20], p[18]); + word3_muladd(&w2, &w1, &w0, ws[21], p[17]); + word3_muladd(&w2, &w1, &w0, ws[22], p[16]); + word3_muladd(&w2, &w1, &w0, ws[23], p[15]); + word3_add(&w2, &w1, &w0, z[38]); + ws[14] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[16], p[23]); + word3_muladd(&w2, &w1, &w0, ws[17], p[22]); + word3_muladd(&w2, &w1, &w0, ws[18], p[21]); + word3_muladd(&w2, &w1, &w0, ws[19], p[20]); + word3_muladd(&w2, &w1, &w0, ws[20], p[19]); + word3_muladd(&w2, &w1, &w0, ws[21], p[18]); + word3_muladd(&w2, &w1, &w0, ws[22], p[17]); + word3_muladd(&w2, &w1, &w0, ws[23], p[16]); + word3_add(&w2, &w1, &w0, z[39]); + ws[15] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[17], p[23]); + word3_muladd(&w2, &w1, &w0, ws[18], p[22]); + word3_muladd(&w2, &w1, &w0, ws[19], p[21]); + word3_muladd(&w2, &w1, &w0, ws[20], p[20]); + word3_muladd(&w2, &w1, &w0, ws[21], p[19]); + word3_muladd(&w2, &w1, &w0, ws[22], p[18]); + word3_muladd(&w2, &w1, &w0, ws[23], p[17]); + word3_add(&w2, &w1, &w0, z[40]); + ws[16] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[18], p[23]); + word3_muladd(&w2, &w1, &w0, ws[19], p[22]); + word3_muladd(&w2, &w1, &w0, ws[20], p[21]); + word3_muladd(&w2, &w1, &w0, ws[21], p[20]); + word3_muladd(&w2, &w1, &w0, ws[22], p[19]); + word3_muladd(&w2, &w1, &w0, ws[23], p[18]); + word3_add(&w2, &w1, &w0, z[41]); + ws[17] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[19], p[23]); + word3_muladd(&w2, &w1, &w0, ws[20], p[22]); + word3_muladd(&w2, &w1, &w0, ws[21], p[21]); + word3_muladd(&w2, &w1, &w0, ws[22], p[20]); + word3_muladd(&w2, &w1, &w0, ws[23], p[19]); + word3_add(&w2, &w1, &w0, z[42]); + ws[18] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[20], p[23]); + word3_muladd(&w2, &w1, &w0, ws[21], p[22]); + word3_muladd(&w2, &w1, &w0, ws[22], p[21]); + word3_muladd(&w2, &w1, &w0, ws[23], p[20]); + word3_add(&w2, &w1, &w0, z[43]); + ws[19] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[21], p[23]); + word3_muladd(&w2, &w1, &w0, ws[22], p[22]); + word3_muladd(&w2, &w1, &w0, ws[23], p[21]); + word3_add(&w2, &w1, &w0, z[44]); + ws[20] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[22], p[23]); + word3_muladd(&w2, &w1, &w0, ws[23], p[22]); + word3_add(&w2, &w1, &w0, z[45]); + ws[21] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[23], p[23]); + word3_add(&w2, &w1, &w0, z[46]); + ws[22] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[47]); + ws[23] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[49]); + ws[24] = w0; + ws[25] = w1; + word borrow = bigint_sub3(ws + 24 + 1, ws, 24 + 1, p, 24); + CT::conditional_copy_mem(borrow, z, ws, ws + 25, 25); + clear_mem(z + 24, 2 * (24 + 1) - 24); +} + +void bigint_monty_redc_32(word z[], const word p[32], word p_dash, word ws[]) { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[6]); + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[6] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[6], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[7]); + word3_muladd(&w2, &w1, &w0, ws[1], p[6]); + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_muladd(&w2, &w1, &w0, ws[6], p[1]); + word3_add(&w2, &w1, &w0, z[7]); + ws[7] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[7], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[8]); + word3_muladd(&w2, &w1, &w0, ws[1], p[7]); + word3_muladd(&w2, &w1, &w0, ws[2], p[6]); + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_muladd(&w2, &w1, &w0, ws[6], p[2]); + word3_muladd(&w2, &w1, &w0, ws[7], p[1]); + word3_add(&w2, &w1, &w0, z[8]); + ws[8] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[8], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[9]); + word3_muladd(&w2, &w1, &w0, ws[1], p[8]); + word3_muladd(&w2, &w1, &w0, ws[2], p[7]); + word3_muladd(&w2, &w1, &w0, ws[3], p[6]); + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_muladd(&w2, &w1, &w0, ws[6], p[3]); + word3_muladd(&w2, &w1, &w0, ws[7], p[2]); + word3_muladd(&w2, &w1, &w0, ws[8], p[1]); + word3_add(&w2, &w1, &w0, z[9]); + ws[9] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[9], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[10]); + word3_muladd(&w2, &w1, &w0, ws[1], p[9]); + word3_muladd(&w2, &w1, &w0, ws[2], p[8]); + word3_muladd(&w2, &w1, &w0, ws[3], p[7]); + word3_muladd(&w2, &w1, &w0, ws[4], p[6]); + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_muladd(&w2, &w1, &w0, ws[6], p[4]); + word3_muladd(&w2, &w1, &w0, ws[7], p[3]); + word3_muladd(&w2, &w1, &w0, ws[8], p[2]); + word3_muladd(&w2, &w1, &w0, ws[9], p[1]); + word3_add(&w2, &w1, &w0, z[10]); + ws[10] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[10], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[11]); + word3_muladd(&w2, &w1, &w0, ws[1], p[10]); + word3_muladd(&w2, &w1, &w0, ws[2], p[9]); + word3_muladd(&w2, &w1, &w0, ws[3], p[8]); + word3_muladd(&w2, &w1, &w0, ws[4], p[7]); + word3_muladd(&w2, &w1, &w0, ws[5], p[6]); + word3_muladd(&w2, &w1, &w0, ws[6], p[5]); + word3_muladd(&w2, &w1, &w0, ws[7], p[4]); + word3_muladd(&w2, &w1, &w0, ws[8], p[3]); + word3_muladd(&w2, &w1, &w0, ws[9], p[2]); + word3_muladd(&w2, &w1, &w0, ws[10], p[1]); + word3_add(&w2, &w1, &w0, z[11]); + ws[11] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[11], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[12]); + word3_muladd(&w2, &w1, &w0, ws[1], p[11]); + word3_muladd(&w2, &w1, &w0, ws[2], p[10]); + word3_muladd(&w2, &w1, &w0, ws[3], p[9]); + word3_muladd(&w2, &w1, &w0, ws[4], p[8]); + word3_muladd(&w2, &w1, &w0, ws[5], p[7]); + word3_muladd(&w2, &w1, &w0, ws[6], p[6]); + word3_muladd(&w2, &w1, &w0, ws[7], p[5]); + word3_muladd(&w2, &w1, &w0, ws[8], p[4]); + word3_muladd(&w2, &w1, &w0, ws[9], p[3]); + word3_muladd(&w2, &w1, &w0, ws[10], p[2]); + word3_muladd(&w2, &w1, &w0, ws[11], p[1]); + word3_add(&w2, &w1, &w0, z[12]); + ws[12] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[12], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[13]); + word3_muladd(&w2, &w1, &w0, ws[1], p[12]); + word3_muladd(&w2, &w1, &w0, ws[2], p[11]); + word3_muladd(&w2, &w1, &w0, ws[3], p[10]); + word3_muladd(&w2, &w1, &w0, ws[4], p[9]); + word3_muladd(&w2, &w1, &w0, ws[5], p[8]); + word3_muladd(&w2, &w1, &w0, ws[6], p[7]); + word3_muladd(&w2, &w1, &w0, ws[7], p[6]); + word3_muladd(&w2, &w1, &w0, ws[8], p[5]); + word3_muladd(&w2, &w1, &w0, ws[9], p[4]); + word3_muladd(&w2, &w1, &w0, ws[10], p[3]); + word3_muladd(&w2, &w1, &w0, ws[11], p[2]); + word3_muladd(&w2, &w1, &w0, ws[12], p[1]); + word3_add(&w2, &w1, &w0, z[13]); + ws[13] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[13], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[14]); + word3_muladd(&w2, &w1, &w0, ws[1], p[13]); + word3_muladd(&w2, &w1, &w0, ws[2], p[12]); + word3_muladd(&w2, &w1, &w0, ws[3], p[11]); + word3_muladd(&w2, &w1, &w0, ws[4], p[10]); + word3_muladd(&w2, &w1, &w0, ws[5], p[9]); + word3_muladd(&w2, &w1, &w0, ws[6], p[8]); + word3_muladd(&w2, &w1, &w0, ws[7], p[7]); + word3_muladd(&w2, &w1, &w0, ws[8], p[6]); + word3_muladd(&w2, &w1, &w0, ws[9], p[5]); + word3_muladd(&w2, &w1, &w0, ws[10], p[4]); + word3_muladd(&w2, &w1, &w0, ws[11], p[3]); + word3_muladd(&w2, &w1, &w0, ws[12], p[2]); + word3_muladd(&w2, &w1, &w0, ws[13], p[1]); + word3_add(&w2, &w1, &w0, z[14]); + ws[14] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[14], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[15]); + word3_muladd(&w2, &w1, &w0, ws[1], p[14]); + word3_muladd(&w2, &w1, &w0, ws[2], p[13]); + word3_muladd(&w2, &w1, &w0, ws[3], p[12]); + word3_muladd(&w2, &w1, &w0, ws[4], p[11]); + word3_muladd(&w2, &w1, &w0, ws[5], p[10]); + word3_muladd(&w2, &w1, &w0, ws[6], p[9]); + word3_muladd(&w2, &w1, &w0, ws[7], p[8]); + word3_muladd(&w2, &w1, &w0, ws[8], p[7]); + word3_muladd(&w2, &w1, &w0, ws[9], p[6]); + word3_muladd(&w2, &w1, &w0, ws[10], p[5]); + word3_muladd(&w2, &w1, &w0, ws[11], p[4]); + word3_muladd(&w2, &w1, &w0, ws[12], p[3]); + word3_muladd(&w2, &w1, &w0, ws[13], p[2]); + word3_muladd(&w2, &w1, &w0, ws[14], p[1]); + word3_add(&w2, &w1, &w0, z[15]); + ws[15] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[15], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[16]); + word3_muladd(&w2, &w1, &w0, ws[1], p[15]); + word3_muladd(&w2, &w1, &w0, ws[2], p[14]); + word3_muladd(&w2, &w1, &w0, ws[3], p[13]); + word3_muladd(&w2, &w1, &w0, ws[4], p[12]); + word3_muladd(&w2, &w1, &w0, ws[5], p[11]); + word3_muladd(&w2, &w1, &w0, ws[6], p[10]); + word3_muladd(&w2, &w1, &w0, ws[7], p[9]); + word3_muladd(&w2, &w1, &w0, ws[8], p[8]); + word3_muladd(&w2, &w1, &w0, ws[9], p[7]); + word3_muladd(&w2, &w1, &w0, ws[10], p[6]); + word3_muladd(&w2, &w1, &w0, ws[11], p[5]); + word3_muladd(&w2, &w1, &w0, ws[12], p[4]); + word3_muladd(&w2, &w1, &w0, ws[13], p[3]); + word3_muladd(&w2, &w1, &w0, ws[14], p[2]); + word3_muladd(&w2, &w1, &w0, ws[15], p[1]); + word3_add(&w2, &w1, &w0, z[16]); + ws[16] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[16], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[17]); + word3_muladd(&w2, &w1, &w0, ws[1], p[16]); + word3_muladd(&w2, &w1, &w0, ws[2], p[15]); + word3_muladd(&w2, &w1, &w0, ws[3], p[14]); + word3_muladd(&w2, &w1, &w0, ws[4], p[13]); + word3_muladd(&w2, &w1, &w0, ws[5], p[12]); + word3_muladd(&w2, &w1, &w0, ws[6], p[11]); + word3_muladd(&w2, &w1, &w0, ws[7], p[10]); + word3_muladd(&w2, &w1, &w0, ws[8], p[9]); + word3_muladd(&w2, &w1, &w0, ws[9], p[8]); + word3_muladd(&w2, &w1, &w0, ws[10], p[7]); + word3_muladd(&w2, &w1, &w0, ws[11], p[6]); + word3_muladd(&w2, &w1, &w0, ws[12], p[5]); + word3_muladd(&w2, &w1, &w0, ws[13], p[4]); + word3_muladd(&w2, &w1, &w0, ws[14], p[3]); + word3_muladd(&w2, &w1, &w0, ws[15], p[2]); + word3_muladd(&w2, &w1, &w0, ws[16], p[1]); + word3_add(&w2, &w1, &w0, z[17]); + ws[17] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[17], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[18]); + word3_muladd(&w2, &w1, &w0, ws[1], p[17]); + word3_muladd(&w2, &w1, &w0, ws[2], p[16]); + word3_muladd(&w2, &w1, &w0, ws[3], p[15]); + word3_muladd(&w2, &w1, &w0, ws[4], p[14]); + word3_muladd(&w2, &w1, &w0, ws[5], p[13]); + word3_muladd(&w2, &w1, &w0, ws[6], p[12]); + word3_muladd(&w2, &w1, &w0, ws[7], p[11]); + word3_muladd(&w2, &w1, &w0, ws[8], p[10]); + word3_muladd(&w2, &w1, &w0, ws[9], p[9]); + word3_muladd(&w2, &w1, &w0, ws[10], p[8]); + word3_muladd(&w2, &w1, &w0, ws[11], p[7]); + word3_muladd(&w2, &w1, &w0, ws[12], p[6]); + word3_muladd(&w2, &w1, &w0, ws[13], p[5]); + word3_muladd(&w2, &w1, &w0, ws[14], p[4]); + word3_muladd(&w2, &w1, &w0, ws[15], p[3]); + word3_muladd(&w2, &w1, &w0, ws[16], p[2]); + word3_muladd(&w2, &w1, &w0, ws[17], p[1]); + word3_add(&w2, &w1, &w0, z[18]); + ws[18] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[18], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[19]); + word3_muladd(&w2, &w1, &w0, ws[1], p[18]); + word3_muladd(&w2, &w1, &w0, ws[2], p[17]); + word3_muladd(&w2, &w1, &w0, ws[3], p[16]); + word3_muladd(&w2, &w1, &w0, ws[4], p[15]); + word3_muladd(&w2, &w1, &w0, ws[5], p[14]); + word3_muladd(&w2, &w1, &w0, ws[6], p[13]); + word3_muladd(&w2, &w1, &w0, ws[7], p[12]); + word3_muladd(&w2, &w1, &w0, ws[8], p[11]); + word3_muladd(&w2, &w1, &w0, ws[9], p[10]); + word3_muladd(&w2, &w1, &w0, ws[10], p[9]); + word3_muladd(&w2, &w1, &w0, ws[11], p[8]); + word3_muladd(&w2, &w1, &w0, ws[12], p[7]); + word3_muladd(&w2, &w1, &w0, ws[13], p[6]); + word3_muladd(&w2, &w1, &w0, ws[14], p[5]); + word3_muladd(&w2, &w1, &w0, ws[15], p[4]); + word3_muladd(&w2, &w1, &w0, ws[16], p[3]); + word3_muladd(&w2, &w1, &w0, ws[17], p[2]); + word3_muladd(&w2, &w1, &w0, ws[18], p[1]); + word3_add(&w2, &w1, &w0, z[19]); + ws[19] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[19], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[20]); + word3_muladd(&w2, &w1, &w0, ws[1], p[19]); + word3_muladd(&w2, &w1, &w0, ws[2], p[18]); + word3_muladd(&w2, &w1, &w0, ws[3], p[17]); + word3_muladd(&w2, &w1, &w0, ws[4], p[16]); + word3_muladd(&w2, &w1, &w0, ws[5], p[15]); + word3_muladd(&w2, &w1, &w0, ws[6], p[14]); + word3_muladd(&w2, &w1, &w0, ws[7], p[13]); + word3_muladd(&w2, &w1, &w0, ws[8], p[12]); + word3_muladd(&w2, &w1, &w0, ws[9], p[11]); + word3_muladd(&w2, &w1, &w0, ws[10], p[10]); + word3_muladd(&w2, &w1, &w0, ws[11], p[9]); + word3_muladd(&w2, &w1, &w0, ws[12], p[8]); + word3_muladd(&w2, &w1, &w0, ws[13], p[7]); + word3_muladd(&w2, &w1, &w0, ws[14], p[6]); + word3_muladd(&w2, &w1, &w0, ws[15], p[5]); + word3_muladd(&w2, &w1, &w0, ws[16], p[4]); + word3_muladd(&w2, &w1, &w0, ws[17], p[3]); + word3_muladd(&w2, &w1, &w0, ws[18], p[2]); + word3_muladd(&w2, &w1, &w0, ws[19], p[1]); + word3_add(&w2, &w1, &w0, z[20]); + ws[20] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[20], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[21]); + word3_muladd(&w2, &w1, &w0, ws[1], p[20]); + word3_muladd(&w2, &w1, &w0, ws[2], p[19]); + word3_muladd(&w2, &w1, &w0, ws[3], p[18]); + word3_muladd(&w2, &w1, &w0, ws[4], p[17]); + word3_muladd(&w2, &w1, &w0, ws[5], p[16]); + word3_muladd(&w2, &w1, &w0, ws[6], p[15]); + word3_muladd(&w2, &w1, &w0, ws[7], p[14]); + word3_muladd(&w2, &w1, &w0, ws[8], p[13]); + word3_muladd(&w2, &w1, &w0, ws[9], p[12]); + word3_muladd(&w2, &w1, &w0, ws[10], p[11]); + word3_muladd(&w2, &w1, &w0, ws[11], p[10]); + word3_muladd(&w2, &w1, &w0, ws[12], p[9]); + word3_muladd(&w2, &w1, &w0, ws[13], p[8]); + word3_muladd(&w2, &w1, &w0, ws[14], p[7]); + word3_muladd(&w2, &w1, &w0, ws[15], p[6]); + word3_muladd(&w2, &w1, &w0, ws[16], p[5]); + word3_muladd(&w2, &w1, &w0, ws[17], p[4]); + word3_muladd(&w2, &w1, &w0, ws[18], p[3]); + word3_muladd(&w2, &w1, &w0, ws[19], p[2]); + word3_muladd(&w2, &w1, &w0, ws[20], p[1]); + word3_add(&w2, &w1, &w0, z[21]); + ws[21] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[21], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[22]); + word3_muladd(&w2, &w1, &w0, ws[1], p[21]); + word3_muladd(&w2, &w1, &w0, ws[2], p[20]); + word3_muladd(&w2, &w1, &w0, ws[3], p[19]); + word3_muladd(&w2, &w1, &w0, ws[4], p[18]); + word3_muladd(&w2, &w1, &w0, ws[5], p[17]); + word3_muladd(&w2, &w1, &w0, ws[6], p[16]); + word3_muladd(&w2, &w1, &w0, ws[7], p[15]); + word3_muladd(&w2, &w1, &w0, ws[8], p[14]); + word3_muladd(&w2, &w1, &w0, ws[9], p[13]); + word3_muladd(&w2, &w1, &w0, ws[10], p[12]); + word3_muladd(&w2, &w1, &w0, ws[11], p[11]); + word3_muladd(&w2, &w1, &w0, ws[12], p[10]); + word3_muladd(&w2, &w1, &w0, ws[13], p[9]); + word3_muladd(&w2, &w1, &w0, ws[14], p[8]); + word3_muladd(&w2, &w1, &w0, ws[15], p[7]); + word3_muladd(&w2, &w1, &w0, ws[16], p[6]); + word3_muladd(&w2, &w1, &w0, ws[17], p[5]); + word3_muladd(&w2, &w1, &w0, ws[18], p[4]); + word3_muladd(&w2, &w1, &w0, ws[19], p[3]); + word3_muladd(&w2, &w1, &w0, ws[20], p[2]); + word3_muladd(&w2, &w1, &w0, ws[21], p[1]); + word3_add(&w2, &w1, &w0, z[22]); + ws[22] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[22], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[23]); + word3_muladd(&w2, &w1, &w0, ws[1], p[22]); + word3_muladd(&w2, &w1, &w0, ws[2], p[21]); + word3_muladd(&w2, &w1, &w0, ws[3], p[20]); + word3_muladd(&w2, &w1, &w0, ws[4], p[19]); + word3_muladd(&w2, &w1, &w0, ws[5], p[18]); + word3_muladd(&w2, &w1, &w0, ws[6], p[17]); + word3_muladd(&w2, &w1, &w0, ws[7], p[16]); + word3_muladd(&w2, &w1, &w0, ws[8], p[15]); + word3_muladd(&w2, &w1, &w0, ws[9], p[14]); + word3_muladd(&w2, &w1, &w0, ws[10], p[13]); + word3_muladd(&w2, &w1, &w0, ws[11], p[12]); + word3_muladd(&w2, &w1, &w0, ws[12], p[11]); + word3_muladd(&w2, &w1, &w0, ws[13], p[10]); + word3_muladd(&w2, &w1, &w0, ws[14], p[9]); + word3_muladd(&w2, &w1, &w0, ws[15], p[8]); + word3_muladd(&w2, &w1, &w0, ws[16], p[7]); + word3_muladd(&w2, &w1, &w0, ws[17], p[6]); + word3_muladd(&w2, &w1, &w0, ws[18], p[5]); + word3_muladd(&w2, &w1, &w0, ws[19], p[4]); + word3_muladd(&w2, &w1, &w0, ws[20], p[3]); + word3_muladd(&w2, &w1, &w0, ws[21], p[2]); + word3_muladd(&w2, &w1, &w0, ws[22], p[1]); + word3_add(&w2, &w1, &w0, z[23]); + ws[23] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[23], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[24]); + word3_muladd(&w2, &w1, &w0, ws[1], p[23]); + word3_muladd(&w2, &w1, &w0, ws[2], p[22]); + word3_muladd(&w2, &w1, &w0, ws[3], p[21]); + word3_muladd(&w2, &w1, &w0, ws[4], p[20]); + word3_muladd(&w2, &w1, &w0, ws[5], p[19]); + word3_muladd(&w2, &w1, &w0, ws[6], p[18]); + word3_muladd(&w2, &w1, &w0, ws[7], p[17]); + word3_muladd(&w2, &w1, &w0, ws[8], p[16]); + word3_muladd(&w2, &w1, &w0, ws[9], p[15]); + word3_muladd(&w2, &w1, &w0, ws[10], p[14]); + word3_muladd(&w2, &w1, &w0, ws[11], p[13]); + word3_muladd(&w2, &w1, &w0, ws[12], p[12]); + word3_muladd(&w2, &w1, &w0, ws[13], p[11]); + word3_muladd(&w2, &w1, &w0, ws[14], p[10]); + word3_muladd(&w2, &w1, &w0, ws[15], p[9]); + word3_muladd(&w2, &w1, &w0, ws[16], p[8]); + word3_muladd(&w2, &w1, &w0, ws[17], p[7]); + word3_muladd(&w2, &w1, &w0, ws[18], p[6]); + word3_muladd(&w2, &w1, &w0, ws[19], p[5]); + word3_muladd(&w2, &w1, &w0, ws[20], p[4]); + word3_muladd(&w2, &w1, &w0, ws[21], p[3]); + word3_muladd(&w2, &w1, &w0, ws[22], p[2]); + word3_muladd(&w2, &w1, &w0, ws[23], p[1]); + word3_add(&w2, &w1, &w0, z[24]); + ws[24] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[24], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[25]); + word3_muladd(&w2, &w1, &w0, ws[1], p[24]); + word3_muladd(&w2, &w1, &w0, ws[2], p[23]); + word3_muladd(&w2, &w1, &w0, ws[3], p[22]); + word3_muladd(&w2, &w1, &w0, ws[4], p[21]); + word3_muladd(&w2, &w1, &w0, ws[5], p[20]); + word3_muladd(&w2, &w1, &w0, ws[6], p[19]); + word3_muladd(&w2, &w1, &w0, ws[7], p[18]); + word3_muladd(&w2, &w1, &w0, ws[8], p[17]); + word3_muladd(&w2, &w1, &w0, ws[9], p[16]); + word3_muladd(&w2, &w1, &w0, ws[10], p[15]); + word3_muladd(&w2, &w1, &w0, ws[11], p[14]); + word3_muladd(&w2, &w1, &w0, ws[12], p[13]); + word3_muladd(&w2, &w1, &w0, ws[13], p[12]); + word3_muladd(&w2, &w1, &w0, ws[14], p[11]); + word3_muladd(&w2, &w1, &w0, ws[15], p[10]); + word3_muladd(&w2, &w1, &w0, ws[16], p[9]); + word3_muladd(&w2, &w1, &w0, ws[17], p[8]); + word3_muladd(&w2, &w1, &w0, ws[18], p[7]); + word3_muladd(&w2, &w1, &w0, ws[19], p[6]); + word3_muladd(&w2, &w1, &w0, ws[20], p[5]); + word3_muladd(&w2, &w1, &w0, ws[21], p[4]); + word3_muladd(&w2, &w1, &w0, ws[22], p[3]); + word3_muladd(&w2, &w1, &w0, ws[23], p[2]); + word3_muladd(&w2, &w1, &w0, ws[24], p[1]); + word3_add(&w2, &w1, &w0, z[25]); + ws[25] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[25], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[26]); + word3_muladd(&w2, &w1, &w0, ws[1], p[25]); + word3_muladd(&w2, &w1, &w0, ws[2], p[24]); + word3_muladd(&w2, &w1, &w0, ws[3], p[23]); + word3_muladd(&w2, &w1, &w0, ws[4], p[22]); + word3_muladd(&w2, &w1, &w0, ws[5], p[21]); + word3_muladd(&w2, &w1, &w0, ws[6], p[20]); + word3_muladd(&w2, &w1, &w0, ws[7], p[19]); + word3_muladd(&w2, &w1, &w0, ws[8], p[18]); + word3_muladd(&w2, &w1, &w0, ws[9], p[17]); + word3_muladd(&w2, &w1, &w0, ws[10], p[16]); + word3_muladd(&w2, &w1, &w0, ws[11], p[15]); + word3_muladd(&w2, &w1, &w0, ws[12], p[14]); + word3_muladd(&w2, &w1, &w0, ws[13], p[13]); + word3_muladd(&w2, &w1, &w0, ws[14], p[12]); + word3_muladd(&w2, &w1, &w0, ws[15], p[11]); + word3_muladd(&w2, &w1, &w0, ws[16], p[10]); + word3_muladd(&w2, &w1, &w0, ws[17], p[9]); + word3_muladd(&w2, &w1, &w0, ws[18], p[8]); + word3_muladd(&w2, &w1, &w0, ws[19], p[7]); + word3_muladd(&w2, &w1, &w0, ws[20], p[6]); + word3_muladd(&w2, &w1, &w0, ws[21], p[5]); + word3_muladd(&w2, &w1, &w0, ws[22], p[4]); + word3_muladd(&w2, &w1, &w0, ws[23], p[3]); + word3_muladd(&w2, &w1, &w0, ws[24], p[2]); + word3_muladd(&w2, &w1, &w0, ws[25], p[1]); + word3_add(&w2, &w1, &w0, z[26]); + ws[26] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[26], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[27]); + word3_muladd(&w2, &w1, &w0, ws[1], p[26]); + word3_muladd(&w2, &w1, &w0, ws[2], p[25]); + word3_muladd(&w2, &w1, &w0, ws[3], p[24]); + word3_muladd(&w2, &w1, &w0, ws[4], p[23]); + word3_muladd(&w2, &w1, &w0, ws[5], p[22]); + word3_muladd(&w2, &w1, &w0, ws[6], p[21]); + word3_muladd(&w2, &w1, &w0, ws[7], p[20]); + word3_muladd(&w2, &w1, &w0, ws[8], p[19]); + word3_muladd(&w2, &w1, &w0, ws[9], p[18]); + word3_muladd(&w2, &w1, &w0, ws[10], p[17]); + word3_muladd(&w2, &w1, &w0, ws[11], p[16]); + word3_muladd(&w2, &w1, &w0, ws[12], p[15]); + word3_muladd(&w2, &w1, &w0, ws[13], p[14]); + word3_muladd(&w2, &w1, &w0, ws[14], p[13]); + word3_muladd(&w2, &w1, &w0, ws[15], p[12]); + word3_muladd(&w2, &w1, &w0, ws[16], p[11]); + word3_muladd(&w2, &w1, &w0, ws[17], p[10]); + word3_muladd(&w2, &w1, &w0, ws[18], p[9]); + word3_muladd(&w2, &w1, &w0, ws[19], p[8]); + word3_muladd(&w2, &w1, &w0, ws[20], p[7]); + word3_muladd(&w2, &w1, &w0, ws[21], p[6]); + word3_muladd(&w2, &w1, &w0, ws[22], p[5]); + word3_muladd(&w2, &w1, &w0, ws[23], p[4]); + word3_muladd(&w2, &w1, &w0, ws[24], p[3]); + word3_muladd(&w2, &w1, &w0, ws[25], p[2]); + word3_muladd(&w2, &w1, &w0, ws[26], p[1]); + word3_add(&w2, &w1, &w0, z[27]); + ws[27] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[27], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[28]); + word3_muladd(&w2, &w1, &w0, ws[1], p[27]); + word3_muladd(&w2, &w1, &w0, ws[2], p[26]); + word3_muladd(&w2, &w1, &w0, ws[3], p[25]); + word3_muladd(&w2, &w1, &w0, ws[4], p[24]); + word3_muladd(&w2, &w1, &w0, ws[5], p[23]); + word3_muladd(&w2, &w1, &w0, ws[6], p[22]); + word3_muladd(&w2, &w1, &w0, ws[7], p[21]); + word3_muladd(&w2, &w1, &w0, ws[8], p[20]); + word3_muladd(&w2, &w1, &w0, ws[9], p[19]); + word3_muladd(&w2, &w1, &w0, ws[10], p[18]); + word3_muladd(&w2, &w1, &w0, ws[11], p[17]); + word3_muladd(&w2, &w1, &w0, ws[12], p[16]); + word3_muladd(&w2, &w1, &w0, ws[13], p[15]); + word3_muladd(&w2, &w1, &w0, ws[14], p[14]); + word3_muladd(&w2, &w1, &w0, ws[15], p[13]); + word3_muladd(&w2, &w1, &w0, ws[16], p[12]); + word3_muladd(&w2, &w1, &w0, ws[17], p[11]); + word3_muladd(&w2, &w1, &w0, ws[18], p[10]); + word3_muladd(&w2, &w1, &w0, ws[19], p[9]); + word3_muladd(&w2, &w1, &w0, ws[20], p[8]); + word3_muladd(&w2, &w1, &w0, ws[21], p[7]); + word3_muladd(&w2, &w1, &w0, ws[22], p[6]); + word3_muladd(&w2, &w1, &w0, ws[23], p[5]); + word3_muladd(&w2, &w1, &w0, ws[24], p[4]); + word3_muladd(&w2, &w1, &w0, ws[25], p[3]); + word3_muladd(&w2, &w1, &w0, ws[26], p[2]); + word3_muladd(&w2, &w1, &w0, ws[27], p[1]); + word3_add(&w2, &w1, &w0, z[28]); + ws[28] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[28], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[29]); + word3_muladd(&w2, &w1, &w0, ws[1], p[28]); + word3_muladd(&w2, &w1, &w0, ws[2], p[27]); + word3_muladd(&w2, &w1, &w0, ws[3], p[26]); + word3_muladd(&w2, &w1, &w0, ws[4], p[25]); + word3_muladd(&w2, &w1, &w0, ws[5], p[24]); + word3_muladd(&w2, &w1, &w0, ws[6], p[23]); + word3_muladd(&w2, &w1, &w0, ws[7], p[22]); + word3_muladd(&w2, &w1, &w0, ws[8], p[21]); + word3_muladd(&w2, &w1, &w0, ws[9], p[20]); + word3_muladd(&w2, &w1, &w0, ws[10], p[19]); + word3_muladd(&w2, &w1, &w0, ws[11], p[18]); + word3_muladd(&w2, &w1, &w0, ws[12], p[17]); + word3_muladd(&w2, &w1, &w0, ws[13], p[16]); + word3_muladd(&w2, &w1, &w0, ws[14], p[15]); + word3_muladd(&w2, &w1, &w0, ws[15], p[14]); + word3_muladd(&w2, &w1, &w0, ws[16], p[13]); + word3_muladd(&w2, &w1, &w0, ws[17], p[12]); + word3_muladd(&w2, &w1, &w0, ws[18], p[11]); + word3_muladd(&w2, &w1, &w0, ws[19], p[10]); + word3_muladd(&w2, &w1, &w0, ws[20], p[9]); + word3_muladd(&w2, &w1, &w0, ws[21], p[8]); + word3_muladd(&w2, &w1, &w0, ws[22], p[7]); + word3_muladd(&w2, &w1, &w0, ws[23], p[6]); + word3_muladd(&w2, &w1, &w0, ws[24], p[5]); + word3_muladd(&w2, &w1, &w0, ws[25], p[4]); + word3_muladd(&w2, &w1, &w0, ws[26], p[3]); + word3_muladd(&w2, &w1, &w0, ws[27], p[2]); + word3_muladd(&w2, &w1, &w0, ws[28], p[1]); + word3_add(&w2, &w1, &w0, z[29]); + ws[29] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[29], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[30]); + word3_muladd(&w2, &w1, &w0, ws[1], p[29]); + word3_muladd(&w2, &w1, &w0, ws[2], p[28]); + word3_muladd(&w2, &w1, &w0, ws[3], p[27]); + word3_muladd(&w2, &w1, &w0, ws[4], p[26]); + word3_muladd(&w2, &w1, &w0, ws[5], p[25]); + word3_muladd(&w2, &w1, &w0, ws[6], p[24]); + word3_muladd(&w2, &w1, &w0, ws[7], p[23]); + word3_muladd(&w2, &w1, &w0, ws[8], p[22]); + word3_muladd(&w2, &w1, &w0, ws[9], p[21]); + word3_muladd(&w2, &w1, &w0, ws[10], p[20]); + word3_muladd(&w2, &w1, &w0, ws[11], p[19]); + word3_muladd(&w2, &w1, &w0, ws[12], p[18]); + word3_muladd(&w2, &w1, &w0, ws[13], p[17]); + word3_muladd(&w2, &w1, &w0, ws[14], p[16]); + word3_muladd(&w2, &w1, &w0, ws[15], p[15]); + word3_muladd(&w2, &w1, &w0, ws[16], p[14]); + word3_muladd(&w2, &w1, &w0, ws[17], p[13]); + word3_muladd(&w2, &w1, &w0, ws[18], p[12]); + word3_muladd(&w2, &w1, &w0, ws[19], p[11]); + word3_muladd(&w2, &w1, &w0, ws[20], p[10]); + word3_muladd(&w2, &w1, &w0, ws[21], p[9]); + word3_muladd(&w2, &w1, &w0, ws[22], p[8]); + word3_muladd(&w2, &w1, &w0, ws[23], p[7]); + word3_muladd(&w2, &w1, &w0, ws[24], p[6]); + word3_muladd(&w2, &w1, &w0, ws[25], p[5]); + word3_muladd(&w2, &w1, &w0, ws[26], p[4]); + word3_muladd(&w2, &w1, &w0, ws[27], p[3]); + word3_muladd(&w2, &w1, &w0, ws[28], p[2]); + word3_muladd(&w2, &w1, &w0, ws[29], p[1]); + word3_add(&w2, &w1, &w0, z[30]); + ws[30] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[30], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[31]); + word3_muladd(&w2, &w1, &w0, ws[1], p[30]); + word3_muladd(&w2, &w1, &w0, ws[2], p[29]); + word3_muladd(&w2, &w1, &w0, ws[3], p[28]); + word3_muladd(&w2, &w1, &w0, ws[4], p[27]); + word3_muladd(&w2, &w1, &w0, ws[5], p[26]); + word3_muladd(&w2, &w1, &w0, ws[6], p[25]); + word3_muladd(&w2, &w1, &w0, ws[7], p[24]); + word3_muladd(&w2, &w1, &w0, ws[8], p[23]); + word3_muladd(&w2, &w1, &w0, ws[9], p[22]); + word3_muladd(&w2, &w1, &w0, ws[10], p[21]); + word3_muladd(&w2, &w1, &w0, ws[11], p[20]); + word3_muladd(&w2, &w1, &w0, ws[12], p[19]); + word3_muladd(&w2, &w1, &w0, ws[13], p[18]); + word3_muladd(&w2, &w1, &w0, ws[14], p[17]); + word3_muladd(&w2, &w1, &w0, ws[15], p[16]); + word3_muladd(&w2, &w1, &w0, ws[16], p[15]); + word3_muladd(&w2, &w1, &w0, ws[17], p[14]); + word3_muladd(&w2, &w1, &w0, ws[18], p[13]); + word3_muladd(&w2, &w1, &w0, ws[19], p[12]); + word3_muladd(&w2, &w1, &w0, ws[20], p[11]); + word3_muladd(&w2, &w1, &w0, ws[21], p[10]); + word3_muladd(&w2, &w1, &w0, ws[22], p[9]); + word3_muladd(&w2, &w1, &w0, ws[23], p[8]); + word3_muladd(&w2, &w1, &w0, ws[24], p[7]); + word3_muladd(&w2, &w1, &w0, ws[25], p[6]); + word3_muladd(&w2, &w1, &w0, ws[26], p[5]); + word3_muladd(&w2, &w1, &w0, ws[27], p[4]); + word3_muladd(&w2, &w1, &w0, ws[28], p[3]); + word3_muladd(&w2, &w1, &w0, ws[29], p[2]); + word3_muladd(&w2, &w1, &w0, ws[30], p[1]); + word3_add(&w2, &w1, &w0, z[31]); + ws[31] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[31], p[0]); + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[31]); + word3_muladd(&w2, &w1, &w0, ws[2], p[30]); + word3_muladd(&w2, &w1, &w0, ws[3], p[29]); + word3_muladd(&w2, &w1, &w0, ws[4], p[28]); + word3_muladd(&w2, &w1, &w0, ws[5], p[27]); + word3_muladd(&w2, &w1, &w0, ws[6], p[26]); + word3_muladd(&w2, &w1, &w0, ws[7], p[25]); + word3_muladd(&w2, &w1, &w0, ws[8], p[24]); + word3_muladd(&w2, &w1, &w0, ws[9], p[23]); + word3_muladd(&w2, &w1, &w0, ws[10], p[22]); + word3_muladd(&w2, &w1, &w0, ws[11], p[21]); + word3_muladd(&w2, &w1, &w0, ws[12], p[20]); + word3_muladd(&w2, &w1, &w0, ws[13], p[19]); + word3_muladd(&w2, &w1, &w0, ws[14], p[18]); + word3_muladd(&w2, &w1, &w0, ws[15], p[17]); + word3_muladd(&w2, &w1, &w0, ws[16], p[16]); + word3_muladd(&w2, &w1, &w0, ws[17], p[15]); + word3_muladd(&w2, &w1, &w0, ws[18], p[14]); + word3_muladd(&w2, &w1, &w0, ws[19], p[13]); + word3_muladd(&w2, &w1, &w0, ws[20], p[12]); + word3_muladd(&w2, &w1, &w0, ws[21], p[11]); + word3_muladd(&w2, &w1, &w0, ws[22], p[10]); + word3_muladd(&w2, &w1, &w0, ws[23], p[9]); + word3_muladd(&w2, &w1, &w0, ws[24], p[8]); + word3_muladd(&w2, &w1, &w0, ws[25], p[7]); + word3_muladd(&w2, &w1, &w0, ws[26], p[6]); + word3_muladd(&w2, &w1, &w0, ws[27], p[5]); + word3_muladd(&w2, &w1, &w0, ws[28], p[4]); + word3_muladd(&w2, &w1, &w0, ws[29], p[3]); + word3_muladd(&w2, &w1, &w0, ws[30], p[2]); + word3_muladd(&w2, &w1, &w0, ws[31], p[1]); + word3_add(&w2, &w1, &w0, z[32]); + ws[0] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[31]); + word3_muladd(&w2, &w1, &w0, ws[3], p[30]); + word3_muladd(&w2, &w1, &w0, ws[4], p[29]); + word3_muladd(&w2, &w1, &w0, ws[5], p[28]); + word3_muladd(&w2, &w1, &w0, ws[6], p[27]); + word3_muladd(&w2, &w1, &w0, ws[7], p[26]); + word3_muladd(&w2, &w1, &w0, ws[8], p[25]); + word3_muladd(&w2, &w1, &w0, ws[9], p[24]); + word3_muladd(&w2, &w1, &w0, ws[10], p[23]); + word3_muladd(&w2, &w1, &w0, ws[11], p[22]); + word3_muladd(&w2, &w1, &w0, ws[12], p[21]); + word3_muladd(&w2, &w1, &w0, ws[13], p[20]); + word3_muladd(&w2, &w1, &w0, ws[14], p[19]); + word3_muladd(&w2, &w1, &w0, ws[15], p[18]); + word3_muladd(&w2, &w1, &w0, ws[16], p[17]); + word3_muladd(&w2, &w1, &w0, ws[17], p[16]); + word3_muladd(&w2, &w1, &w0, ws[18], p[15]); + word3_muladd(&w2, &w1, &w0, ws[19], p[14]); + word3_muladd(&w2, &w1, &w0, ws[20], p[13]); + word3_muladd(&w2, &w1, &w0, ws[21], p[12]); + word3_muladd(&w2, &w1, &w0, ws[22], p[11]); + word3_muladd(&w2, &w1, &w0, ws[23], p[10]); + word3_muladd(&w2, &w1, &w0, ws[24], p[9]); + word3_muladd(&w2, &w1, &w0, ws[25], p[8]); + word3_muladd(&w2, &w1, &w0, ws[26], p[7]); + word3_muladd(&w2, &w1, &w0, ws[27], p[6]); + word3_muladd(&w2, &w1, &w0, ws[28], p[5]); + word3_muladd(&w2, &w1, &w0, ws[29], p[4]); + word3_muladd(&w2, &w1, &w0, ws[30], p[3]); + word3_muladd(&w2, &w1, &w0, ws[31], p[2]); + word3_add(&w2, &w1, &w0, z[33]); + ws[1] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[31]); + word3_muladd(&w2, &w1, &w0, ws[4], p[30]); + word3_muladd(&w2, &w1, &w0, ws[5], p[29]); + word3_muladd(&w2, &w1, &w0, ws[6], p[28]); + word3_muladd(&w2, &w1, &w0, ws[7], p[27]); + word3_muladd(&w2, &w1, &w0, ws[8], p[26]); + word3_muladd(&w2, &w1, &w0, ws[9], p[25]); + word3_muladd(&w2, &w1, &w0, ws[10], p[24]); + word3_muladd(&w2, &w1, &w0, ws[11], p[23]); + word3_muladd(&w2, &w1, &w0, ws[12], p[22]); + word3_muladd(&w2, &w1, &w0, ws[13], p[21]); + word3_muladd(&w2, &w1, &w0, ws[14], p[20]); + word3_muladd(&w2, &w1, &w0, ws[15], p[19]); + word3_muladd(&w2, &w1, &w0, ws[16], p[18]); + word3_muladd(&w2, &w1, &w0, ws[17], p[17]); + word3_muladd(&w2, &w1, &w0, ws[18], p[16]); + word3_muladd(&w2, &w1, &w0, ws[19], p[15]); + word3_muladd(&w2, &w1, &w0, ws[20], p[14]); + word3_muladd(&w2, &w1, &w0, ws[21], p[13]); + word3_muladd(&w2, &w1, &w0, ws[22], p[12]); + word3_muladd(&w2, &w1, &w0, ws[23], p[11]); + word3_muladd(&w2, &w1, &w0, ws[24], p[10]); + word3_muladd(&w2, &w1, &w0, ws[25], p[9]); + word3_muladd(&w2, &w1, &w0, ws[26], p[8]); + word3_muladd(&w2, &w1, &w0, ws[27], p[7]); + word3_muladd(&w2, &w1, &w0, ws[28], p[6]); + word3_muladd(&w2, &w1, &w0, ws[29], p[5]); + word3_muladd(&w2, &w1, &w0, ws[30], p[4]); + word3_muladd(&w2, &w1, &w0, ws[31], p[3]); + word3_add(&w2, &w1, &w0, z[34]); + ws[2] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[31]); + word3_muladd(&w2, &w1, &w0, ws[5], p[30]); + word3_muladd(&w2, &w1, &w0, ws[6], p[29]); + word3_muladd(&w2, &w1, &w0, ws[7], p[28]); + word3_muladd(&w2, &w1, &w0, ws[8], p[27]); + word3_muladd(&w2, &w1, &w0, ws[9], p[26]); + word3_muladd(&w2, &w1, &w0, ws[10], p[25]); + word3_muladd(&w2, &w1, &w0, ws[11], p[24]); + word3_muladd(&w2, &w1, &w0, ws[12], p[23]); + word3_muladd(&w2, &w1, &w0, ws[13], p[22]); + word3_muladd(&w2, &w1, &w0, ws[14], p[21]); + word3_muladd(&w2, &w1, &w0, ws[15], p[20]); + word3_muladd(&w2, &w1, &w0, ws[16], p[19]); + word3_muladd(&w2, &w1, &w0, ws[17], p[18]); + word3_muladd(&w2, &w1, &w0, ws[18], p[17]); + word3_muladd(&w2, &w1, &w0, ws[19], p[16]); + word3_muladd(&w2, &w1, &w0, ws[20], p[15]); + word3_muladd(&w2, &w1, &w0, ws[21], p[14]); + word3_muladd(&w2, &w1, &w0, ws[22], p[13]); + word3_muladd(&w2, &w1, &w0, ws[23], p[12]); + word3_muladd(&w2, &w1, &w0, ws[24], p[11]); + word3_muladd(&w2, &w1, &w0, ws[25], p[10]); + word3_muladd(&w2, &w1, &w0, ws[26], p[9]); + word3_muladd(&w2, &w1, &w0, ws[27], p[8]); + word3_muladd(&w2, &w1, &w0, ws[28], p[7]); + word3_muladd(&w2, &w1, &w0, ws[29], p[6]); + word3_muladd(&w2, &w1, &w0, ws[30], p[5]); + word3_muladd(&w2, &w1, &w0, ws[31], p[4]); + word3_add(&w2, &w1, &w0, z[35]); + ws[3] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[31]); + word3_muladd(&w2, &w1, &w0, ws[6], p[30]); + word3_muladd(&w2, &w1, &w0, ws[7], p[29]); + word3_muladd(&w2, &w1, &w0, ws[8], p[28]); + word3_muladd(&w2, &w1, &w0, ws[9], p[27]); + word3_muladd(&w2, &w1, &w0, ws[10], p[26]); + word3_muladd(&w2, &w1, &w0, ws[11], p[25]); + word3_muladd(&w2, &w1, &w0, ws[12], p[24]); + word3_muladd(&w2, &w1, &w0, ws[13], p[23]); + word3_muladd(&w2, &w1, &w0, ws[14], p[22]); + word3_muladd(&w2, &w1, &w0, ws[15], p[21]); + word3_muladd(&w2, &w1, &w0, ws[16], p[20]); + word3_muladd(&w2, &w1, &w0, ws[17], p[19]); + word3_muladd(&w2, &w1, &w0, ws[18], p[18]); + word3_muladd(&w2, &w1, &w0, ws[19], p[17]); + word3_muladd(&w2, &w1, &w0, ws[20], p[16]); + word3_muladd(&w2, &w1, &w0, ws[21], p[15]); + word3_muladd(&w2, &w1, &w0, ws[22], p[14]); + word3_muladd(&w2, &w1, &w0, ws[23], p[13]); + word3_muladd(&w2, &w1, &w0, ws[24], p[12]); + word3_muladd(&w2, &w1, &w0, ws[25], p[11]); + word3_muladd(&w2, &w1, &w0, ws[26], p[10]); + word3_muladd(&w2, &w1, &w0, ws[27], p[9]); + word3_muladd(&w2, &w1, &w0, ws[28], p[8]); + word3_muladd(&w2, &w1, &w0, ws[29], p[7]); + word3_muladd(&w2, &w1, &w0, ws[30], p[6]); + word3_muladd(&w2, &w1, &w0, ws[31], p[5]); + word3_add(&w2, &w1, &w0, z[36]); + ws[4] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[6], p[31]); + word3_muladd(&w2, &w1, &w0, ws[7], p[30]); + word3_muladd(&w2, &w1, &w0, ws[8], p[29]); + word3_muladd(&w2, &w1, &w0, ws[9], p[28]); + word3_muladd(&w2, &w1, &w0, ws[10], p[27]); + word3_muladd(&w2, &w1, &w0, ws[11], p[26]); + word3_muladd(&w2, &w1, &w0, ws[12], p[25]); + word3_muladd(&w2, &w1, &w0, ws[13], p[24]); + word3_muladd(&w2, &w1, &w0, ws[14], p[23]); + word3_muladd(&w2, &w1, &w0, ws[15], p[22]); + word3_muladd(&w2, &w1, &w0, ws[16], p[21]); + word3_muladd(&w2, &w1, &w0, ws[17], p[20]); + word3_muladd(&w2, &w1, &w0, ws[18], p[19]); + word3_muladd(&w2, &w1, &w0, ws[19], p[18]); + word3_muladd(&w2, &w1, &w0, ws[20], p[17]); + word3_muladd(&w2, &w1, &w0, ws[21], p[16]); + word3_muladd(&w2, &w1, &w0, ws[22], p[15]); + word3_muladd(&w2, &w1, &w0, ws[23], p[14]); + word3_muladd(&w2, &w1, &w0, ws[24], p[13]); + word3_muladd(&w2, &w1, &w0, ws[25], p[12]); + word3_muladd(&w2, &w1, &w0, ws[26], p[11]); + word3_muladd(&w2, &w1, &w0, ws[27], p[10]); + word3_muladd(&w2, &w1, &w0, ws[28], p[9]); + word3_muladd(&w2, &w1, &w0, ws[29], p[8]); + word3_muladd(&w2, &w1, &w0, ws[30], p[7]); + word3_muladd(&w2, &w1, &w0, ws[31], p[6]); + word3_add(&w2, &w1, &w0, z[37]); + ws[5] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[7], p[31]); + word3_muladd(&w2, &w1, &w0, ws[8], p[30]); + word3_muladd(&w2, &w1, &w0, ws[9], p[29]); + word3_muladd(&w2, &w1, &w0, ws[10], p[28]); + word3_muladd(&w2, &w1, &w0, ws[11], p[27]); + word3_muladd(&w2, &w1, &w0, ws[12], p[26]); + word3_muladd(&w2, &w1, &w0, ws[13], p[25]); + word3_muladd(&w2, &w1, &w0, ws[14], p[24]); + word3_muladd(&w2, &w1, &w0, ws[15], p[23]); + word3_muladd(&w2, &w1, &w0, ws[16], p[22]); + word3_muladd(&w2, &w1, &w0, ws[17], p[21]); + word3_muladd(&w2, &w1, &w0, ws[18], p[20]); + word3_muladd(&w2, &w1, &w0, ws[19], p[19]); + word3_muladd(&w2, &w1, &w0, ws[20], p[18]); + word3_muladd(&w2, &w1, &w0, ws[21], p[17]); + word3_muladd(&w2, &w1, &w0, ws[22], p[16]); + word3_muladd(&w2, &w1, &w0, ws[23], p[15]); + word3_muladd(&w2, &w1, &w0, ws[24], p[14]); + word3_muladd(&w2, &w1, &w0, ws[25], p[13]); + word3_muladd(&w2, &w1, &w0, ws[26], p[12]); + word3_muladd(&w2, &w1, &w0, ws[27], p[11]); + word3_muladd(&w2, &w1, &w0, ws[28], p[10]); + word3_muladd(&w2, &w1, &w0, ws[29], p[9]); + word3_muladd(&w2, &w1, &w0, ws[30], p[8]); + word3_muladd(&w2, &w1, &w0, ws[31], p[7]); + word3_add(&w2, &w1, &w0, z[38]); + ws[6] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[8], p[31]); + word3_muladd(&w2, &w1, &w0, ws[9], p[30]); + word3_muladd(&w2, &w1, &w0, ws[10], p[29]); + word3_muladd(&w2, &w1, &w0, ws[11], p[28]); + word3_muladd(&w2, &w1, &w0, ws[12], p[27]); + word3_muladd(&w2, &w1, &w0, ws[13], p[26]); + word3_muladd(&w2, &w1, &w0, ws[14], p[25]); + word3_muladd(&w2, &w1, &w0, ws[15], p[24]); + word3_muladd(&w2, &w1, &w0, ws[16], p[23]); + word3_muladd(&w2, &w1, &w0, ws[17], p[22]); + word3_muladd(&w2, &w1, &w0, ws[18], p[21]); + word3_muladd(&w2, &w1, &w0, ws[19], p[20]); + word3_muladd(&w2, &w1, &w0, ws[20], p[19]); + word3_muladd(&w2, &w1, &w0, ws[21], p[18]); + word3_muladd(&w2, &w1, &w0, ws[22], p[17]); + word3_muladd(&w2, &w1, &w0, ws[23], p[16]); + word3_muladd(&w2, &w1, &w0, ws[24], p[15]); + word3_muladd(&w2, &w1, &w0, ws[25], p[14]); + word3_muladd(&w2, &w1, &w0, ws[26], p[13]); + word3_muladd(&w2, &w1, &w0, ws[27], p[12]); + word3_muladd(&w2, &w1, &w0, ws[28], p[11]); + word3_muladd(&w2, &w1, &w0, ws[29], p[10]); + word3_muladd(&w2, &w1, &w0, ws[30], p[9]); + word3_muladd(&w2, &w1, &w0, ws[31], p[8]); + word3_add(&w2, &w1, &w0, z[39]); + ws[7] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[9], p[31]); + word3_muladd(&w2, &w1, &w0, ws[10], p[30]); + word3_muladd(&w2, &w1, &w0, ws[11], p[29]); + word3_muladd(&w2, &w1, &w0, ws[12], p[28]); + word3_muladd(&w2, &w1, &w0, ws[13], p[27]); + word3_muladd(&w2, &w1, &w0, ws[14], p[26]); + word3_muladd(&w2, &w1, &w0, ws[15], p[25]); + word3_muladd(&w2, &w1, &w0, ws[16], p[24]); + word3_muladd(&w2, &w1, &w0, ws[17], p[23]); + word3_muladd(&w2, &w1, &w0, ws[18], p[22]); + word3_muladd(&w2, &w1, &w0, ws[19], p[21]); + word3_muladd(&w2, &w1, &w0, ws[20], p[20]); + word3_muladd(&w2, &w1, &w0, ws[21], p[19]); + word3_muladd(&w2, &w1, &w0, ws[22], p[18]); + word3_muladd(&w2, &w1, &w0, ws[23], p[17]); + word3_muladd(&w2, &w1, &w0, ws[24], p[16]); + word3_muladd(&w2, &w1, &w0, ws[25], p[15]); + word3_muladd(&w2, &w1, &w0, ws[26], p[14]); + word3_muladd(&w2, &w1, &w0, ws[27], p[13]); + word3_muladd(&w2, &w1, &w0, ws[28], p[12]); + word3_muladd(&w2, &w1, &w0, ws[29], p[11]); + word3_muladd(&w2, &w1, &w0, ws[30], p[10]); + word3_muladd(&w2, &w1, &w0, ws[31], p[9]); + word3_add(&w2, &w1, &w0, z[40]); + ws[8] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[10], p[31]); + word3_muladd(&w2, &w1, &w0, ws[11], p[30]); + word3_muladd(&w2, &w1, &w0, ws[12], p[29]); + word3_muladd(&w2, &w1, &w0, ws[13], p[28]); + word3_muladd(&w2, &w1, &w0, ws[14], p[27]); + word3_muladd(&w2, &w1, &w0, ws[15], p[26]); + word3_muladd(&w2, &w1, &w0, ws[16], p[25]); + word3_muladd(&w2, &w1, &w0, ws[17], p[24]); + word3_muladd(&w2, &w1, &w0, ws[18], p[23]); + word3_muladd(&w2, &w1, &w0, ws[19], p[22]); + word3_muladd(&w2, &w1, &w0, ws[20], p[21]); + word3_muladd(&w2, &w1, &w0, ws[21], p[20]); + word3_muladd(&w2, &w1, &w0, ws[22], p[19]); + word3_muladd(&w2, &w1, &w0, ws[23], p[18]); + word3_muladd(&w2, &w1, &w0, ws[24], p[17]); + word3_muladd(&w2, &w1, &w0, ws[25], p[16]); + word3_muladd(&w2, &w1, &w0, ws[26], p[15]); + word3_muladd(&w2, &w1, &w0, ws[27], p[14]); + word3_muladd(&w2, &w1, &w0, ws[28], p[13]); + word3_muladd(&w2, &w1, &w0, ws[29], p[12]); + word3_muladd(&w2, &w1, &w0, ws[30], p[11]); + word3_muladd(&w2, &w1, &w0, ws[31], p[10]); + word3_add(&w2, &w1, &w0, z[41]); + ws[9] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[11], p[31]); + word3_muladd(&w2, &w1, &w0, ws[12], p[30]); + word3_muladd(&w2, &w1, &w0, ws[13], p[29]); + word3_muladd(&w2, &w1, &w0, ws[14], p[28]); + word3_muladd(&w2, &w1, &w0, ws[15], p[27]); + word3_muladd(&w2, &w1, &w0, ws[16], p[26]); + word3_muladd(&w2, &w1, &w0, ws[17], p[25]); + word3_muladd(&w2, &w1, &w0, ws[18], p[24]); + word3_muladd(&w2, &w1, &w0, ws[19], p[23]); + word3_muladd(&w2, &w1, &w0, ws[20], p[22]); + word3_muladd(&w2, &w1, &w0, ws[21], p[21]); + word3_muladd(&w2, &w1, &w0, ws[22], p[20]); + word3_muladd(&w2, &w1, &w0, ws[23], p[19]); + word3_muladd(&w2, &w1, &w0, ws[24], p[18]); + word3_muladd(&w2, &w1, &w0, ws[25], p[17]); + word3_muladd(&w2, &w1, &w0, ws[26], p[16]); + word3_muladd(&w2, &w1, &w0, ws[27], p[15]); + word3_muladd(&w2, &w1, &w0, ws[28], p[14]); + word3_muladd(&w2, &w1, &w0, ws[29], p[13]); + word3_muladd(&w2, &w1, &w0, ws[30], p[12]); + word3_muladd(&w2, &w1, &w0, ws[31], p[11]); + word3_add(&w2, &w1, &w0, z[42]); + ws[10] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[12], p[31]); + word3_muladd(&w2, &w1, &w0, ws[13], p[30]); + word3_muladd(&w2, &w1, &w0, ws[14], p[29]); + word3_muladd(&w2, &w1, &w0, ws[15], p[28]); + word3_muladd(&w2, &w1, &w0, ws[16], p[27]); + word3_muladd(&w2, &w1, &w0, ws[17], p[26]); + word3_muladd(&w2, &w1, &w0, ws[18], p[25]); + word3_muladd(&w2, &w1, &w0, ws[19], p[24]); + word3_muladd(&w2, &w1, &w0, ws[20], p[23]); + word3_muladd(&w2, &w1, &w0, ws[21], p[22]); + word3_muladd(&w2, &w1, &w0, ws[22], p[21]); + word3_muladd(&w2, &w1, &w0, ws[23], p[20]); + word3_muladd(&w2, &w1, &w0, ws[24], p[19]); + word3_muladd(&w2, &w1, &w0, ws[25], p[18]); + word3_muladd(&w2, &w1, &w0, ws[26], p[17]); + word3_muladd(&w2, &w1, &w0, ws[27], p[16]); + word3_muladd(&w2, &w1, &w0, ws[28], p[15]); + word3_muladd(&w2, &w1, &w0, ws[29], p[14]); + word3_muladd(&w2, &w1, &w0, ws[30], p[13]); + word3_muladd(&w2, &w1, &w0, ws[31], p[12]); + word3_add(&w2, &w1, &w0, z[43]); + ws[11] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[13], p[31]); + word3_muladd(&w2, &w1, &w0, ws[14], p[30]); + word3_muladd(&w2, &w1, &w0, ws[15], p[29]); + word3_muladd(&w2, &w1, &w0, ws[16], p[28]); + word3_muladd(&w2, &w1, &w0, ws[17], p[27]); + word3_muladd(&w2, &w1, &w0, ws[18], p[26]); + word3_muladd(&w2, &w1, &w0, ws[19], p[25]); + word3_muladd(&w2, &w1, &w0, ws[20], p[24]); + word3_muladd(&w2, &w1, &w0, ws[21], p[23]); + word3_muladd(&w2, &w1, &w0, ws[22], p[22]); + word3_muladd(&w2, &w1, &w0, ws[23], p[21]); + word3_muladd(&w2, &w1, &w0, ws[24], p[20]); + word3_muladd(&w2, &w1, &w0, ws[25], p[19]); + word3_muladd(&w2, &w1, &w0, ws[26], p[18]); + word3_muladd(&w2, &w1, &w0, ws[27], p[17]); + word3_muladd(&w2, &w1, &w0, ws[28], p[16]); + word3_muladd(&w2, &w1, &w0, ws[29], p[15]); + word3_muladd(&w2, &w1, &w0, ws[30], p[14]); + word3_muladd(&w2, &w1, &w0, ws[31], p[13]); + word3_add(&w2, &w1, &w0, z[44]); + ws[12] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[14], p[31]); + word3_muladd(&w2, &w1, &w0, ws[15], p[30]); + word3_muladd(&w2, &w1, &w0, ws[16], p[29]); + word3_muladd(&w2, &w1, &w0, ws[17], p[28]); + word3_muladd(&w2, &w1, &w0, ws[18], p[27]); + word3_muladd(&w2, &w1, &w0, ws[19], p[26]); + word3_muladd(&w2, &w1, &w0, ws[20], p[25]); + word3_muladd(&w2, &w1, &w0, ws[21], p[24]); + word3_muladd(&w2, &w1, &w0, ws[22], p[23]); + word3_muladd(&w2, &w1, &w0, ws[23], p[22]); + word3_muladd(&w2, &w1, &w0, ws[24], p[21]); + word3_muladd(&w2, &w1, &w0, ws[25], p[20]); + word3_muladd(&w2, &w1, &w0, ws[26], p[19]); + word3_muladd(&w2, &w1, &w0, ws[27], p[18]); + word3_muladd(&w2, &w1, &w0, ws[28], p[17]); + word3_muladd(&w2, &w1, &w0, ws[29], p[16]); + word3_muladd(&w2, &w1, &w0, ws[30], p[15]); + word3_muladd(&w2, &w1, &w0, ws[31], p[14]); + word3_add(&w2, &w1, &w0, z[45]); + ws[13] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[15], p[31]); + word3_muladd(&w2, &w1, &w0, ws[16], p[30]); + word3_muladd(&w2, &w1, &w0, ws[17], p[29]); + word3_muladd(&w2, &w1, &w0, ws[18], p[28]); + word3_muladd(&w2, &w1, &w0, ws[19], p[27]); + word3_muladd(&w2, &w1, &w0, ws[20], p[26]); + word3_muladd(&w2, &w1, &w0, ws[21], p[25]); + word3_muladd(&w2, &w1, &w0, ws[22], p[24]); + word3_muladd(&w2, &w1, &w0, ws[23], p[23]); + word3_muladd(&w2, &w1, &w0, ws[24], p[22]); + word3_muladd(&w2, &w1, &w0, ws[25], p[21]); + word3_muladd(&w2, &w1, &w0, ws[26], p[20]); + word3_muladd(&w2, &w1, &w0, ws[27], p[19]); + word3_muladd(&w2, &w1, &w0, ws[28], p[18]); + word3_muladd(&w2, &w1, &w0, ws[29], p[17]); + word3_muladd(&w2, &w1, &w0, ws[30], p[16]); + word3_muladd(&w2, &w1, &w0, ws[31], p[15]); + word3_add(&w2, &w1, &w0, z[46]); + ws[14] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[16], p[31]); + word3_muladd(&w2, &w1, &w0, ws[17], p[30]); + word3_muladd(&w2, &w1, &w0, ws[18], p[29]); + word3_muladd(&w2, &w1, &w0, ws[19], p[28]); + word3_muladd(&w2, &w1, &w0, ws[20], p[27]); + word3_muladd(&w2, &w1, &w0, ws[21], p[26]); + word3_muladd(&w2, &w1, &w0, ws[22], p[25]); + word3_muladd(&w2, &w1, &w0, ws[23], p[24]); + word3_muladd(&w2, &w1, &w0, ws[24], p[23]); + word3_muladd(&w2, &w1, &w0, ws[25], p[22]); + word3_muladd(&w2, &w1, &w0, ws[26], p[21]); + word3_muladd(&w2, &w1, &w0, ws[27], p[20]); + word3_muladd(&w2, &w1, &w0, ws[28], p[19]); + word3_muladd(&w2, &w1, &w0, ws[29], p[18]); + word3_muladd(&w2, &w1, &w0, ws[30], p[17]); + word3_muladd(&w2, &w1, &w0, ws[31], p[16]); + word3_add(&w2, &w1, &w0, z[47]); + ws[15] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[17], p[31]); + word3_muladd(&w2, &w1, &w0, ws[18], p[30]); + word3_muladd(&w2, &w1, &w0, ws[19], p[29]); + word3_muladd(&w2, &w1, &w0, ws[20], p[28]); + word3_muladd(&w2, &w1, &w0, ws[21], p[27]); + word3_muladd(&w2, &w1, &w0, ws[22], p[26]); + word3_muladd(&w2, &w1, &w0, ws[23], p[25]); + word3_muladd(&w2, &w1, &w0, ws[24], p[24]); + word3_muladd(&w2, &w1, &w0, ws[25], p[23]); + word3_muladd(&w2, &w1, &w0, ws[26], p[22]); + word3_muladd(&w2, &w1, &w0, ws[27], p[21]); + word3_muladd(&w2, &w1, &w0, ws[28], p[20]); + word3_muladd(&w2, &w1, &w0, ws[29], p[19]); + word3_muladd(&w2, &w1, &w0, ws[30], p[18]); + word3_muladd(&w2, &w1, &w0, ws[31], p[17]); + word3_add(&w2, &w1, &w0, z[48]); + ws[16] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[18], p[31]); + word3_muladd(&w2, &w1, &w0, ws[19], p[30]); + word3_muladd(&w2, &w1, &w0, ws[20], p[29]); + word3_muladd(&w2, &w1, &w0, ws[21], p[28]); + word3_muladd(&w2, &w1, &w0, ws[22], p[27]); + word3_muladd(&w2, &w1, &w0, ws[23], p[26]); + word3_muladd(&w2, &w1, &w0, ws[24], p[25]); + word3_muladd(&w2, &w1, &w0, ws[25], p[24]); + word3_muladd(&w2, &w1, &w0, ws[26], p[23]); + word3_muladd(&w2, &w1, &w0, ws[27], p[22]); + word3_muladd(&w2, &w1, &w0, ws[28], p[21]); + word3_muladd(&w2, &w1, &w0, ws[29], p[20]); + word3_muladd(&w2, &w1, &w0, ws[30], p[19]); + word3_muladd(&w2, &w1, &w0, ws[31], p[18]); + word3_add(&w2, &w1, &w0, z[49]); + ws[17] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[19], p[31]); + word3_muladd(&w2, &w1, &w0, ws[20], p[30]); + word3_muladd(&w2, &w1, &w0, ws[21], p[29]); + word3_muladd(&w2, &w1, &w0, ws[22], p[28]); + word3_muladd(&w2, &w1, &w0, ws[23], p[27]); + word3_muladd(&w2, &w1, &w0, ws[24], p[26]); + word3_muladd(&w2, &w1, &w0, ws[25], p[25]); + word3_muladd(&w2, &w1, &w0, ws[26], p[24]); + word3_muladd(&w2, &w1, &w0, ws[27], p[23]); + word3_muladd(&w2, &w1, &w0, ws[28], p[22]); + word3_muladd(&w2, &w1, &w0, ws[29], p[21]); + word3_muladd(&w2, &w1, &w0, ws[30], p[20]); + word3_muladd(&w2, &w1, &w0, ws[31], p[19]); + word3_add(&w2, &w1, &w0, z[50]); + ws[18] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[20], p[31]); + word3_muladd(&w2, &w1, &w0, ws[21], p[30]); + word3_muladd(&w2, &w1, &w0, ws[22], p[29]); + word3_muladd(&w2, &w1, &w0, ws[23], p[28]); + word3_muladd(&w2, &w1, &w0, ws[24], p[27]); + word3_muladd(&w2, &w1, &w0, ws[25], p[26]); + word3_muladd(&w2, &w1, &w0, ws[26], p[25]); + word3_muladd(&w2, &w1, &w0, ws[27], p[24]); + word3_muladd(&w2, &w1, &w0, ws[28], p[23]); + word3_muladd(&w2, &w1, &w0, ws[29], p[22]); + word3_muladd(&w2, &w1, &w0, ws[30], p[21]); + word3_muladd(&w2, &w1, &w0, ws[31], p[20]); + word3_add(&w2, &w1, &w0, z[51]); + ws[19] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[21], p[31]); + word3_muladd(&w2, &w1, &w0, ws[22], p[30]); + word3_muladd(&w2, &w1, &w0, ws[23], p[29]); + word3_muladd(&w2, &w1, &w0, ws[24], p[28]); + word3_muladd(&w2, &w1, &w0, ws[25], p[27]); + word3_muladd(&w2, &w1, &w0, ws[26], p[26]); + word3_muladd(&w2, &w1, &w0, ws[27], p[25]); + word3_muladd(&w2, &w1, &w0, ws[28], p[24]); + word3_muladd(&w2, &w1, &w0, ws[29], p[23]); + word3_muladd(&w2, &w1, &w0, ws[30], p[22]); + word3_muladd(&w2, &w1, &w0, ws[31], p[21]); + word3_add(&w2, &w1, &w0, z[52]); + ws[20] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[22], p[31]); + word3_muladd(&w2, &w1, &w0, ws[23], p[30]); + word3_muladd(&w2, &w1, &w0, ws[24], p[29]); + word3_muladd(&w2, &w1, &w0, ws[25], p[28]); + word3_muladd(&w2, &w1, &w0, ws[26], p[27]); + word3_muladd(&w2, &w1, &w0, ws[27], p[26]); + word3_muladd(&w2, &w1, &w0, ws[28], p[25]); + word3_muladd(&w2, &w1, &w0, ws[29], p[24]); + word3_muladd(&w2, &w1, &w0, ws[30], p[23]); + word3_muladd(&w2, &w1, &w0, ws[31], p[22]); + word3_add(&w2, &w1, &w0, z[53]); + ws[21] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[23], p[31]); + word3_muladd(&w2, &w1, &w0, ws[24], p[30]); + word3_muladd(&w2, &w1, &w0, ws[25], p[29]); + word3_muladd(&w2, &w1, &w0, ws[26], p[28]); + word3_muladd(&w2, &w1, &w0, ws[27], p[27]); + word3_muladd(&w2, &w1, &w0, ws[28], p[26]); + word3_muladd(&w2, &w1, &w0, ws[29], p[25]); + word3_muladd(&w2, &w1, &w0, ws[30], p[24]); + word3_muladd(&w2, &w1, &w0, ws[31], p[23]); + word3_add(&w2, &w1, &w0, z[54]); + ws[22] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[24], p[31]); + word3_muladd(&w2, &w1, &w0, ws[25], p[30]); + word3_muladd(&w2, &w1, &w0, ws[26], p[29]); + word3_muladd(&w2, &w1, &w0, ws[27], p[28]); + word3_muladd(&w2, &w1, &w0, ws[28], p[27]); + word3_muladd(&w2, &w1, &w0, ws[29], p[26]); + word3_muladd(&w2, &w1, &w0, ws[30], p[25]); + word3_muladd(&w2, &w1, &w0, ws[31], p[24]); + word3_add(&w2, &w1, &w0, z[55]); + ws[23] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[25], p[31]); + word3_muladd(&w2, &w1, &w0, ws[26], p[30]); + word3_muladd(&w2, &w1, &w0, ws[27], p[29]); + word3_muladd(&w2, &w1, &w0, ws[28], p[28]); + word3_muladd(&w2, &w1, &w0, ws[29], p[27]); + word3_muladd(&w2, &w1, &w0, ws[30], p[26]); + word3_muladd(&w2, &w1, &w0, ws[31], p[25]); + word3_add(&w2, &w1, &w0, z[56]); + ws[24] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[26], p[31]); + word3_muladd(&w2, &w1, &w0, ws[27], p[30]); + word3_muladd(&w2, &w1, &w0, ws[28], p[29]); + word3_muladd(&w2, &w1, &w0, ws[29], p[28]); + word3_muladd(&w2, &w1, &w0, ws[30], p[27]); + word3_muladd(&w2, &w1, &w0, ws[31], p[26]); + word3_add(&w2, &w1, &w0, z[57]); + ws[25] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[27], p[31]); + word3_muladd(&w2, &w1, &w0, ws[28], p[30]); + word3_muladd(&w2, &w1, &w0, ws[29], p[29]); + word3_muladd(&w2, &w1, &w0, ws[30], p[28]); + word3_muladd(&w2, &w1, &w0, ws[31], p[27]); + word3_add(&w2, &w1, &w0, z[58]); + ws[26] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[28], p[31]); + word3_muladd(&w2, &w1, &w0, ws[29], p[30]); + word3_muladd(&w2, &w1, &w0, ws[30], p[29]); + word3_muladd(&w2, &w1, &w0, ws[31], p[28]); + word3_add(&w2, &w1, &w0, z[59]); + ws[27] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[29], p[31]); + word3_muladd(&w2, &w1, &w0, ws[30], p[30]); + word3_muladd(&w2, &w1, &w0, ws[31], p[29]); + word3_add(&w2, &w1, &w0, z[60]); + ws[28] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[30], p[31]); + word3_muladd(&w2, &w1, &w0, ws[31], p[30]); + word3_add(&w2, &w1, &w0, z[61]); + ws[29] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[31], p[31]); + word3_add(&w2, &w1, &w0, z[62]); + ws[30] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[63]); + ws[31] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + word3_add(&w2, &w1, &w0, z[65]); + ws[32] = w0; + ws[33] = w1; + word borrow = bigint_sub3(ws + 32 + 1, ws, 32 + 1, p, 32); + CT::conditional_copy_mem(borrow, z, ws, ws + 33, 33); + clear_mem(z + 32, 2 * (32 + 1) - 32); +} + +} // namespace Botan +/* + * DSA Parameter Generation + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { /* -* Check if this size is allowed by FIPS 186-3 -*/ -bool fips186_3_valid_size(size_t pbits, size_t qbits) - { - if(qbits == 160) - return (pbits == 1024); + * Check if this size is allowed by FIPS 186-3 + */ +bool fips186_3_valid_size(size_t pbits, size_t qbits) { + if (qbits == 160) return (pbits == 1024); - if(qbits == 224) - return (pbits == 2048); + if (qbits == 224) return (pbits == 2048); - if(qbits == 256) - return (pbits == 2048 || pbits == 3072); - - return false; - } + if (qbits == 256) return (pbits == 2048 || pbits == 3072); + return false; } +} // namespace + /* -* Attempt DSA prime generation with given seed -*/ -bool generate_dsa_primes(RandomNumberGenerator& rng, - BigInt& p, BigInt& q, - size_t pbits, size_t qbits, - const std::vector& seed_c, - size_t offset) - { - if(!fips186_3_valid_size(pbits, qbits)) - throw Invalid_Argument( - "FIPS 186-3 does not allow DSA domain parameters of " + - std::to_string(pbits) + "/" + std::to_string(qbits) + " bits long"); + * Attempt DSA prime generation with given seed + */ +bool generate_dsa_primes(RandomNumberGenerator& rng, BigInt& p, BigInt& q, size_t pbits, + size_t qbits, const std::vector& seed_c, size_t offset) { + if (!fips186_3_valid_size(pbits, qbits)) + throw Invalid_Argument("FIPS 186-3 does not allow DSA domain parameters of " + + std::to_string(pbits) + "/" + std::to_string(qbits) + " bits long"); - if(seed_c.size() * 8 < qbits) - throw Invalid_Argument( - "Generating a DSA parameter set with a " + std::to_string(qbits) + - " bit long q requires a seed at least as many bits long"); + if (seed_c.size() * 8 < qbits) + throw Invalid_Argument("Generating a DSA parameter set with a " + std::to_string(qbits) + + " bit long q requires a seed at least as many bits long"); - const std::string hash_name = "SHA-" + std::to_string(qbits); - std::unique_ptr hash(HashFunction::create_or_throw(hash_name)); + const std::string hash_name = "SHA-" + std::to_string(qbits); + std::unique_ptr hash(HashFunction::create_or_throw(hash_name)); - const size_t HASH_SIZE = hash->output_length(); + const size_t HASH_SIZE = hash->output_length(); - class Seed final - { - public: - explicit Seed(const std::vector& s) : m_seed(s) {} + class Seed final { + public: + explicit Seed(const std::vector& s) : m_seed(s) {} - const std::vector& value() const { return m_seed; } + const std::vector& value() const { return m_seed; } - Seed& operator++() - { - for(size_t j = m_seed.size(); j > 0; --j) - if(++m_seed[j-1]) - break; + Seed& operator++() { + for (size_t j = m_seed.size(); j > 0; --j) + if (++m_seed[j - 1]) break; return (*this); - } - private: - std::vector m_seed; - }; + } - Seed seed(seed_c); + private: + std::vector m_seed; + }; - q.binary_decode(hash->process(seed.value())); - q.set_bit(qbits-1); - q.set_bit(0); + Seed seed(seed_c); - if(!is_prime(q, rng, 128, true)) - return false; + q.binary_decode(hash->process(seed.value())); + q.set_bit(qbits - 1); + q.set_bit(0); - const size_t n = (pbits-1) / (HASH_SIZE * 8), - b = (pbits-1) % (HASH_SIZE * 8); + if (!is_prime(q, rng, 128, true)) return false; - BigInt X; - std::vector V(HASH_SIZE * (n+1)); + const size_t n = (pbits - 1) / (HASH_SIZE * 8), b = (pbits - 1) % (HASH_SIZE * 8); - Modular_Reducer mod_2q(2*q); + BigInt X; + std::vector V(HASH_SIZE * (n + 1)); - for(size_t j = 0; j != 4*pbits; ++j) - { - for(size_t k = 0; k <= n; ++k) - { - ++seed; - hash->update(seed.value()); - hash->final(&V[HASH_SIZE * (n-k)]); - } + Modular_Reducer mod_2q(2 * q); - if(j >= offset) - { - X.binary_decode(&V[HASH_SIZE - 1 - b/8], - V.size() - (HASH_SIZE - 1 - b/8)); - X.set_bit(pbits-1); + for (size_t j = 0; j != 4 * pbits; ++j) { + for (size_t k = 0; k <= n; ++k) { + ++seed; + hash->update(seed.value()); + hash->final(&V[HASH_SIZE * (n - k)]); + } - p = X - (mod_2q.reduce(X) - 1); + if (j >= offset) { + X.binary_decode(&V[HASH_SIZE - 1 - b / 8], V.size() - (HASH_SIZE - 1 - b / 8)); + X.set_bit(pbits - 1); - if(p.bits() == pbits && is_prime(p, rng, 128, true)) - return true; - } - } - return false; - } - -/* -* Generate DSA Primes -*/ -std::vector generate_dsa_primes(RandomNumberGenerator& rng, - BigInt& p, BigInt& q, - size_t pbits, size_t qbits) - { - while(true) - { - std::vector seed(qbits / 8); - rng.randomize(seed.data(), seed.size()); - - if(generate_dsa_primes(rng, p, q, pbits, qbits, seed)) - return seed; - } - } + p = X - (mod_2q.reduce(X) - 1); + if (p.bits() == pbits && is_prime(p, rng, 128, true)) return true; + } + } + return false; } -/* -* Jacobi Function -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Generate DSA Primes + */ +std::vector generate_dsa_primes(RandomNumberGenerator& rng, BigInt& p, BigInt& q, + size_t pbits, size_t qbits) { + while (true) { + std::vector seed(qbits / 8); + rng.randomize(seed.data(), seed.size()); + + if (generate_dsa_primes(rng, p, q, pbits, qbits, seed)) return seed; + } +} + +} // namespace Botan +/* + * Jacobi Function + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Calculate the Jacobi symbol -*/ -int32_t jacobi(const BigInt& a, const BigInt& n) - { - if(n.is_even() || n < 2) - throw Invalid_Argument("jacobi: second argument must be odd and > 1"); + * Calculate the Jacobi symbol + */ +int32_t jacobi(const BigInt& a, const BigInt& n) { + if (n.is_even() || n < 2) throw Invalid_Argument("jacobi: second argument must be odd and > 1"); - BigInt x = a % n; - BigInt y = n; - int32_t J = 1; + BigInt x = a % n; + BigInt y = n; + int32_t J = 1; - while(y > 1) - { - x %= y; - if(x > y / 2) - { - x = y - x; - if(y % 4 == 3) - J = -J; - } - if(x.is_zero()) - return 0; + while (y > 1) { + x %= y; + if (x > y / 2) { + x = y - x; + if (y % 4 == 3) J = -J; + } + if (x.is_zero()) return 0; - size_t shifts = low_zero_bits(x); - x >>= shifts; - if(shifts % 2) - { - word y_mod_8 = y % 8; - if(y_mod_8 == 3 || y_mod_8 == 5) - J = -J; - } - - if(x % 4 == 3 && y % 4 == 3) - J = -J; - std::swap(x, y); - } - return J; - } + size_t shifts = low_zero_bits(x); + x >>= shifts; + if (shifts % 2) { + word y_mod_8 = y % 8; + if (y_mod_8 == 3 || y_mod_8 == 5) J = -J; + } + if (x % 4 == 3 && y % 4 == 3) J = -J; + std::swap(x, y); + } + return J; } -/* -* Prime Generation -* (C) 1999-2007,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * Prime Generation + * (C) 1999-2007,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { -class Prime_Sieve final - { +class Prime_Sieve final { public: - Prime_Sieve(const BigInt& init_value, size_t sieve_size) : - m_sieve(std::min(sieve_size, PRIME_TABLE_SIZE)) - { - for(size_t i = 0; i != m_sieve.size(); ++i) + Prime_Sieve(const BigInt& init_value, size_t sieve_size) + : m_sieve(std::min(sieve_size, PRIME_TABLE_SIZE)) { + for (size_t i = 0; i != m_sieve.size(); ++i) m_sieve[i] = static_cast(init_value % PRIMES[i]); - } + } - void step(word increment) - { - for(size_t i = 0; i != m_sieve.size(); ++i) - { + void step(word increment) { + for (size_t i = 0; i != m_sieve.size(); ++i) { m_sieve[i] = (m_sieve[i] + increment) % PRIMES[i]; - } - } + } + } - bool passes(bool check_2p1 = false) const - { - for(size_t i = 0; i != m_sieve.size(); ++i) - { + bool passes(bool check_2p1 = false) const { + for (size_t i = 0; i != m_sieve.size(); ++i) { /* In this case, p is a multiple of PRIMES[i] */ - if(m_sieve[i] == 0) - return false; + if (m_sieve[i] == 0) return false; - if(check_2p1) - { - /* - In this case, 2*p+1 will be a multiple of PRIMES[i] + if (check_2p1) { + /* + In this case, 2*p+1 will be a multiple of PRIMES[i] - So if potentially generating a safe prime, we want to - avoid this value because 2*p+1 will certainly not be prime. + So if potentially generating a safe prime, we want to + avoid this value because 2*p+1 will certainly not be prime. - See "Safe Prime Generation with a Combined Sieve" M. Wiener - https://eprint.iacr.org/2003/186.pdf - */ - if(m_sieve[i] == (PRIMES[i] - 1) / 2) - return false; - } + See "Safe Prime Generation with a Combined Sieve" M. Wiener + https://eprint.iacr.org/2003/186.pdf + */ + if (m_sieve[i] == (PRIMES[i] - 1) / 2) return false; } + } - return true; - } + return true; + } private: - std::vector m_sieve; - }; - -} + std::vector m_sieve; +}; +} // namespace /* -* Generate a random prime -*/ -BigInt random_prime(RandomNumberGenerator& rng, - size_t bits, const BigInt& coprime, - size_t equiv, size_t modulo, - size_t prob) - { - if(coprime.is_negative()) - { - throw Invalid_Argument("random_prime: coprime must be >= 0"); - } - if(modulo == 0) - { - throw Invalid_Argument("random_prime: Invalid modulo value"); - } + * Generate a random prime + */ +BigInt random_prime(RandomNumberGenerator& rng, size_t bits, const BigInt& coprime, size_t equiv, + size_t modulo, size_t prob) { + if (coprime.is_negative()) { + throw Invalid_Argument("random_prime: coprime must be >= 0"); + } + if (modulo == 0) { + throw Invalid_Argument("random_prime: Invalid modulo value"); + } - equiv %= modulo; + equiv %= modulo; - if(equiv == 0) - throw Invalid_Argument("random_prime Invalid value for equiv/modulo"); + if (equiv == 0) throw Invalid_Argument("random_prime Invalid value for equiv/modulo"); - // Handle small values: - if(bits <= 1) - { - throw Invalid_Argument("random_prime: Can't make a prime of " + - std::to_string(bits) + " bits"); - } - else if(bits == 2) - { - return ((rng.next_byte() % 2) ? 2 : 3); - } - else if(bits == 3) - { - return ((rng.next_byte() % 2) ? 5 : 7); - } - else if(bits == 4) - { - return ((rng.next_byte() % 2) ? 11 : 13); - } - else if(bits <= 16) - { - for(;;) - { - // This is slightly biased, but for small primes it does not seem to matter - const uint8_t b0 = rng.next_byte(); - const uint8_t b1 = rng.next_byte(); - const size_t idx = make_uint16(b0, b1) % PRIME_TABLE_SIZE; - const uint16_t small_prime = PRIMES[idx]; + // Handle small values: + if (bits <= 1) { + throw Invalid_Argument("random_prime: Can't make a prime of " + std::to_string(bits) + + " bits"); + } else if (bits == 2) { + return ((rng.next_byte() % 2) ? 2 : 3); + } else if (bits == 3) { + return ((rng.next_byte() % 2) ? 5 : 7); + } else if (bits == 4) { + return ((rng.next_byte() % 2) ? 11 : 13); + } else if (bits <= 16) { + for (;;) { + // This is slightly biased, but for small primes it does not seem to matter + const uint8_t b0 = rng.next_byte(); + const uint8_t b1 = rng.next_byte(); + const size_t idx = make_uint16(b0, b1) % PRIME_TABLE_SIZE; + const uint16_t small_prime = PRIMES[idx]; - if(high_bit(small_prime) == bits) - return small_prime; - } - } + if (high_bit(small_prime) == bits) return small_prime; + } + } - const size_t MAX_ATTEMPTS = 32*1024; + const size_t MAX_ATTEMPTS = 32 * 1024; - while(true) - { - BigInt p(rng, bits); + while (true) { + BigInt p(rng, bits); - // Force lowest and two top bits on - p.set_bit(bits - 1); - p.set_bit(bits - 2); - p.set_bit(0); + // Force lowest and two top bits on + p.set_bit(bits - 1); + p.set_bit(bits - 2); + p.set_bit(0); - // Force p to be equal to equiv mod modulo - p += (modulo - (p % modulo)) + equiv; + // Force p to be equal to equiv mod modulo + p += (modulo - (p % modulo)) + equiv; - Prime_Sieve sieve(p, bits); + Prime_Sieve sieve(p, bits); - size_t counter = 0; - while(true) - { - ++counter; + size_t counter = 0; + while (true) { + ++counter; - if(counter > MAX_ATTEMPTS) - { - break; // don't try forever, choose a new starting point + if (counter > MAX_ATTEMPTS) { + break; // don't try forever, choose a new starting point } - p += modulo; + p += modulo; - sieve.step(modulo); + sieve.step(modulo); - if(sieve.passes(true) == false) - continue; + if (sieve.passes(true) == false) continue; + + if (coprime > 1) { + /* + * Check if gcd(p - 1, coprime) != 1 by computing the inverse. The + * gcd algorithm is not constant time, but modular inverse is (for + * odd modulus anyway). This avoids a side channel attack against RSA + * key generation, though RSA keygen should be using generate_rsa_prime. + */ + if (inverse_mod(p - 1, coprime).is_zero()) continue; + } + + if (p.bits() > bits) break; + + if (is_prime(p, rng, prob, true)) return p; + } + } +} + +BigInt generate_rsa_prime(RandomNumberGenerator& keygen_rng, RandomNumberGenerator& prime_test_rng, + size_t bits, const BigInt& coprime, size_t prob) { + if (bits < 512) throw Invalid_Argument("generate_rsa_prime bits too small"); + + /* + * The restriction on coprime <= 64 bits is arbitrary but generally speaking + * very large RSA public exponents are a bad idea both for performance and due + * to attacks on small d. + */ + if (coprime <= 1 || coprime.is_even() || coprime.bits() > 64) + throw Invalid_Argument("generate_rsa_prime coprime must be small odd positive integer"); + + const size_t MAX_ATTEMPTS = 32 * 1024; + + while (true) { + BigInt p(keygen_rng, bits); + + // Force lowest and two top bits on + p.set_bit(bits - 1); + p.set_bit(bits - 2); + p.set_bit(0); + + Prime_Sieve sieve(p, bits); + + const word step = 2; + + size_t counter = 0; + while (true) { + ++counter; + + if (counter > MAX_ATTEMPTS) { + break; // don't try forever, choose a new starting point + } + + p += step; + + sieve.step(step); + + if (sieve.passes() == false) continue; - if(coprime > 1) - { /* - * Check if gcd(p - 1, coprime) != 1 by computing the inverse. The - * gcd algorithm is not constant time, but modular inverse is (for - * odd modulus anyway). This avoids a side channel attack against RSA - * key generation, though RSA keygen should be using generate_rsa_prime. - */ - if(inverse_mod(p - 1, coprime).is_zero()) - continue; + * Check if p - 1 and coprime are relatively prime by computing the inverse. + * + * We avoid gcd here because that algorithm is not constant time. + * Modular inverse is (for odd modulus anyway). + * + * We earlier verified that coprime argument is odd. Thus the factors of 2 + * in (p - 1) cannot possibly be factors in coprime, so remove them from p - 1. + * Using an odd modulus allows the const time algorithm to be used. + * + * This assumes coprime < p - 1 which is always true for RSA. + */ + BigInt p1 = p - 1; + p1 >>= low_zero_bits(p1); + if (inverse_mod(coprime, p1).is_zero()) { + BOTAN_DEBUG_ASSERT(gcd(p1, coprime) > 1); + continue; } - if(p.bits() > bits) - break; + BOTAN_DEBUG_ASSERT(gcd(p1, coprime) == 1); - if(is_prime(p, rng, prob, true)) - return p; - } - } - } - -BigInt generate_rsa_prime(RandomNumberGenerator& keygen_rng, - RandomNumberGenerator& prime_test_rng, - size_t bits, - const BigInt& coprime, - size_t prob) - { - if(bits < 512) - throw Invalid_Argument("generate_rsa_prime bits too small"); - - /* - * The restriction on coprime <= 64 bits is arbitrary but generally speaking - * very large RSA public exponents are a bad idea both for performance and due - * to attacks on small d. - */ - if(coprime <= 1 || coprime.is_even() || coprime.bits() > 64) - throw Invalid_Argument("generate_rsa_prime coprime must be small odd positive integer"); - - const size_t MAX_ATTEMPTS = 32*1024; - - while(true) - { - BigInt p(keygen_rng, bits); - - // Force lowest and two top bits on - p.set_bit(bits - 1); - p.set_bit(bits - 2); - p.set_bit(0); - - Prime_Sieve sieve(p, bits); - - const word step = 2; - - size_t counter = 0; - while(true) - { - ++counter; - - if(counter > MAX_ATTEMPTS) - { - break; // don't try forever, choose a new starting point - } - - p += step; - - sieve.step(step); - - if(sieve.passes() == false) - continue; - - /* - * Check if p - 1 and coprime are relatively prime by computing the inverse. - * - * We avoid gcd here because that algorithm is not constant time. - * Modular inverse is (for odd modulus anyway). - * - * We earlier verified that coprime argument is odd. Thus the factors of 2 - * in (p - 1) cannot possibly be factors in coprime, so remove them from p - 1. - * Using an odd modulus allows the const time algorithm to be used. - * - * This assumes coprime < p - 1 which is always true for RSA. - */ - BigInt p1 = p - 1; - p1 >>= low_zero_bits(p1); - if(inverse_mod(coprime, p1).is_zero()) - { - BOTAN_DEBUG_ASSERT(gcd(p1, coprime) > 1); - continue; - } - - BOTAN_DEBUG_ASSERT(gcd(p1, coprime) == 1); - - if(p.bits() > bits) - break; - - if(is_prime(p, prime_test_rng, prob, true)) - return p; - } - } - } - -/* -* Generate a random safe prime -*/ -BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits) - { - if(bits <= 64) - throw Invalid_Argument("random_safe_prime: Can't make a prime of " + - std::to_string(bits) + " bits"); - - BigInt q, p; - for(;;) - { - /* - Generate q == 2 (mod 3) - - Otherwise [q == 1 (mod 3) case], 2*q+1 == 3 (mod 3) and not prime. - - Initially allow a very high error prob (1/2**8) to allow for fast checks, - then if 2*q+1 turns out to be a prime go back and strongly check q. - */ - q = random_prime(rng, bits - 1, 0, 2, 3, 8); - p = (q << 1) + 1; - - if(is_prime(p, rng, 128, true)) - { - // We did only a weak check before, go back and verify q before returning - if(is_prime(q, rng, 128, true)) - return p; - } - } - } + if (p.bits() > bits) break; + if (is_prime(p, prime_test_rng, prob, true)) return p; + } + } } -/* -* (C) 2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Generate a random safe prime + */ +BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits) { + if (bits <= 64) + throw Invalid_Argument("random_safe_prime: Can't make a prime of " + std::to_string(bits) + + " bits"); + + BigInt q, p; + for (;;) { + /* + Generate q == 2 (mod 3) + + Otherwise [q == 1 (mod 3) case], 2*q+1 == 3 (mod 3) and not prime. + + Initially allow a very high error prob (1/2**8) to allow for fast checks, + then if 2*q+1 turns out to be a prime go back and strongly check q. + */ + q = random_prime(rng, bits - 1, 0, 2, 3, 8); + p = (q << 1) + 1; + + if (is_prime(p, rng, 128, true)) { + // We did only a weak check before, go back and verify q before returning + if (is_prime(q, rng, 128, true)) return p; + } + } +} + +} // namespace Botan +/* + * (C) 2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -Montgomery_Params::Montgomery_Params(const BigInt& p, - const Modular_Reducer& mod_p) - { - if(p.is_even() || p < 3) - throw Invalid_Argument("Montgomery_Params invalid modulus"); +Montgomery_Params::Montgomery_Params(const BigInt& p, const Modular_Reducer& mod_p) { + if (p.is_even() || p < 3) throw Invalid_Argument("Montgomery_Params invalid modulus"); - m_p = p; - m_p_words = m_p.sig_words(); - m_p_dash = monty_inverse(m_p.word_at(0)); + m_p = p; + m_p_words = m_p.sig_words(); + m_p_dash = monty_inverse(m_p.word_at(0)); - const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS); + const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS); - m_r1 = mod_p.reduce(r); - m_r2 = mod_p.square(m_r1); - m_r3 = mod_p.multiply(m_r1, m_r2); - } + m_r1 = mod_p.reduce(r); + m_r2 = mod_p.square(m_r1); + m_r3 = mod_p.multiply(m_r1, m_r2); +} -Montgomery_Params::Montgomery_Params(const BigInt& p) - { +Montgomery_Params::Montgomery_Params(const BigInt& p) { + if (p.is_negative() || p.is_even()) throw Invalid_Argument("Montgomery_Params invalid modulus"); - if(p.is_negative() || p.is_even()) - throw Invalid_Argument("Montgomery_Params invalid modulus"); + m_p = p; + m_p_words = m_p.sig_words(); + m_p_dash = monty_inverse(m_p.word_at(0)); - m_p = p; - m_p_words = m_p.sig_words(); - m_p_dash = monty_inverse(m_p.word_at(0)); + const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS); - const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS); + // It might be faster to use ct_modulo here vs setting up Barrett reduction? + Modular_Reducer mod_p(p); - // It might be faster to use ct_modulo here vs setting up Barrett reduction? - Modular_Reducer mod_p(p); + m_r1 = mod_p.reduce(r); + m_r2 = mod_p.square(m_r1); + m_r3 = mod_p.multiply(m_r1, m_r2); +} - m_r1 = mod_p.reduce(r); - m_r2 = mod_p.square(m_r1); - m_r3 = mod_p.multiply(m_r1, m_r2); - } +BigInt Montgomery_Params::inv_mod_p(const BigInt& x) const { + return ct_inverse_mod_odd_modulus(x, p()); +} -BigInt Montgomery_Params::inv_mod_p(const BigInt& x) const - { - return ct_inverse_mod_odd_modulus(x, p()); - } +BigInt Montgomery_Params::redc(const BigInt& x, secure_vector& ws) const { + const size_t output_size = 2 * m_p_words + 2; -BigInt Montgomery_Params::redc(const BigInt& x, secure_vector& ws) const - { - const size_t output_size = 2*m_p_words + 2; + if (ws.size() < output_size) ws.resize(output_size); - if(ws.size() < output_size) - ws.resize(output_size); + BigInt z = x; + z.grow_to(output_size); - BigInt z = x; - z.grow_to(output_size); + bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_p_dash, ws.data(), ws.size()); - bigint_monty_redc(z.mutable_data(), - m_p.data(), m_p_words, m_p_dash, - ws.data(), ws.size()); + return z; +} - return z; - } +BigInt Montgomery_Params::mul(const BigInt& x, const BigInt& y, secure_vector& ws) const { + const size_t output_size = 2 * m_p_words + 2; -BigInt Montgomery_Params::mul(const BigInt& x, const BigInt& y, - secure_vector& ws) const - { - const size_t output_size = 2*m_p_words + 2; + if (ws.size() < output_size) ws.resize(output_size); - if(ws.size() < output_size) - ws.resize(output_size); + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); + BigInt z(BigInt::Positive, output_size); + bigint_mul(z.mutable_data(), z.size(), x.data(), x.size(), std::min(m_p_words, x.size()), + y.data(), y.size(), std::min(m_p_words, y.size()), ws.data(), ws.size()); - BigInt z(BigInt::Positive, output_size); - bigint_mul(z.mutable_data(), z.size(), - x.data(), x.size(), std::min(m_p_words, x.size()), - y.data(), y.size(), std::min(m_p_words, y.size()), - ws.data(), ws.size()); + bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_p_dash, ws.data(), ws.size()); - bigint_monty_redc(z.mutable_data(), - m_p.data(), m_p_words, m_p_dash, - ws.data(), ws.size()); + return z; +} - return z; - } +BigInt Montgomery_Params::mul(const BigInt& x, const secure_vector& y, + secure_vector& ws) const { + const size_t output_size = 2 * m_p_words + 2; + if (ws.size() < output_size) ws.resize(output_size); + BigInt z(BigInt::Positive, output_size); -BigInt Montgomery_Params::mul(const BigInt& x, - const secure_vector& y, - secure_vector& ws) const - { - const size_t output_size = 2*m_p_words + 2; - if(ws.size() < output_size) - ws.resize(output_size); - BigInt z(BigInt::Positive, output_size); + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + bigint_mul(z.mutable_data(), z.size(), x.data(), x.size(), std::min(m_p_words, x.size()), + y.data(), y.size(), std::min(m_p_words, y.size()), ws.data(), ws.size()); - bigint_mul(z.mutable_data(), z.size(), - x.data(), x.size(), std::min(m_p_words, x.size()), - y.data(), y.size(), std::min(m_p_words, y.size()), - ws.data(), ws.size()); + bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_p_dash, ws.data(), ws.size()); - bigint_monty_redc(z.mutable_data(), - m_p.data(), m_p_words, m_p_dash, - ws.data(), ws.size()); + return z; +} - return z; - } +void Montgomery_Params::mul_by(BigInt& x, const secure_vector& y, + secure_vector& ws) const { + const size_t output_size = 2 * m_p_words + 2; -void Montgomery_Params::mul_by(BigInt& x, - const secure_vector& y, - secure_vector& ws) const - { - const size_t output_size = 2*m_p_words + 2; + if (ws.size() < 2 * output_size) ws.resize(2 * output_size); - if(ws.size() < 2*output_size) - ws.resize(2*output_size); + word* z_data = &ws[0]; + word* ws_data = &ws[output_size]; - word* z_data = &ws[0]; - word* ws_data = &ws[output_size]; + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + bigint_mul(z_data, output_size, x.data(), x.size(), std::min(m_p_words, x.size()), y.data(), + y.size(), std::min(m_p_words, y.size()), ws_data, output_size); - bigint_mul(z_data, output_size, - x.data(), x.size(), std::min(m_p_words, x.size()), - y.data(), y.size(), std::min(m_p_words, y.size()), - ws_data, output_size); + bigint_monty_redc(z_data, m_p.data(), m_p_words, m_p_dash, ws_data, output_size); - bigint_monty_redc(z_data, - m_p.data(), m_p_words, m_p_dash, - ws_data, output_size); + if (x.size() < output_size) x.grow_to(output_size); + copy_mem(x.mutable_data(), z_data, output_size); +} - if(x.size() < output_size) - x.grow_to(output_size); - copy_mem(x.mutable_data(), z_data, output_size); - } +void Montgomery_Params::mul_by(BigInt& x, const BigInt& y, secure_vector& ws) const { + const size_t output_size = 2 * m_p_words + 2; -void Montgomery_Params::mul_by(BigInt& x, - const BigInt& y, - secure_vector& ws) const - { - const size_t output_size = 2*m_p_words + 2; + if (ws.size() < 2 * output_size) ws.resize(2 * output_size); - if(ws.size() < 2*output_size) - ws.resize(2*output_size); + word* z_data = &ws[0]; + word* ws_data = &ws[output_size]; - word* z_data = &ws[0]; - word* ws_data = &ws[output_size]; + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + bigint_mul(z_data, output_size, x.data(), x.size(), std::min(m_p_words, x.size()), y.data(), + y.size(), std::min(m_p_words, y.size()), ws_data, output_size); - bigint_mul(z_data, output_size, - x.data(), x.size(), std::min(m_p_words, x.size()), - y.data(), y.size(), std::min(m_p_words, y.size()), - ws_data, output_size); + bigint_monty_redc(z_data, m_p.data(), m_p_words, m_p_dash, ws_data, output_size); - bigint_monty_redc(z_data, - m_p.data(), m_p_words, m_p_dash, - ws_data, output_size); + if (x.size() < output_size) x.grow_to(output_size); + copy_mem(x.mutable_data(), z_data, output_size); +} - if(x.size() < output_size) - x.grow_to(output_size); - copy_mem(x.mutable_data(), z_data, output_size); - } +BigInt Montgomery_Params::sqr(const BigInt& x, secure_vector& ws) const { + const size_t output_size = 2 * m_p_words + 2; -BigInt Montgomery_Params::sqr(const BigInt& x, secure_vector& ws) const - { - const size_t output_size = 2*m_p_words + 2; + if (ws.size() < output_size) ws.resize(output_size); - if(ws.size() < output_size) - ws.resize(output_size); + BigInt z(BigInt::Positive, output_size); - BigInt z(BigInt::Positive, output_size); + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + bigint_sqr(z.mutable_data(), z.size(), x.data(), x.size(), std::min(m_p_words, x.size()), + ws.data(), ws.size()); - bigint_sqr(z.mutable_data(), z.size(), - x.data(), x.size(), std::min(m_p_words, x.size()), - ws.data(), ws.size()); + bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_p_dash, ws.data(), ws.size()); - bigint_monty_redc(z.mutable_data(), - m_p.data(), m_p_words, m_p_dash, - ws.data(), ws.size()); + return z; +} - return z; - } +void Montgomery_Params::square_this(BigInt& x, secure_vector& ws) const { + const size_t output_size = 2 * m_p_words + 2; -void Montgomery_Params::square_this(BigInt& x, - secure_vector& ws) const - { - const size_t output_size = 2*m_p_words + 2; + if (ws.size() < 2 * output_size) ws.resize(2 * output_size); - if(ws.size() < 2*output_size) - ws.resize(2*output_size); + word* z_data = &ws[0]; + word* ws_data = &ws[output_size]; - word* z_data = &ws[0]; - word* ws_data = &ws[output_size]; + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); - BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + bigint_sqr(z_data, output_size, x.data(), x.size(), std::min(m_p_words, x.size()), ws_data, + output_size); - bigint_sqr(z_data, output_size, - x.data(), x.size(), std::min(m_p_words, x.size()), - ws_data, output_size); + bigint_monty_redc(z_data, m_p.data(), m_p_words, m_p_dash, ws_data, output_size); - bigint_monty_redc(z_data, - m_p.data(), m_p_words, m_p_dash, - ws_data, output_size); - - if(x.size() < output_size) - x.grow_to(output_size); - copy_mem(x.mutable_data(), z_data, output_size); - } + if (x.size() < output_size) x.grow_to(output_size); + copy_mem(x.mutable_data(), z_data, output_size); +} Montgomery_Int::Montgomery_Int(const std::shared_ptr params, - const BigInt& v, - bool redc_needed) : - m_params(params) - { - if(redc_needed == false) - { - m_v = v; - } - else - { - BOTAN_ASSERT_NOMSG(m_v < m_params->p()); - secure_vector ws; - m_v = m_params->mul(v, m_params->R2(), ws); - } - } - -Montgomery_Int::Montgomery_Int(std::shared_ptr params, - const uint8_t bits[], size_t len, - bool redc_needed) : - m_params(params), - m_v(bits, len) - { - if(redc_needed) - { - BOTAN_ASSERT_NOMSG(m_v < m_params->p()); - secure_vector ws; - m_v = m_params->mul(m_v, m_params->R2(), ws); - } - } - -Montgomery_Int::Montgomery_Int(std::shared_ptr params, - const word words[], size_t len, - bool redc_needed) : - m_params(params), - m_v(words, len) - { - if(redc_needed) - { - BOTAN_ASSERT_NOMSG(m_v < m_params->p()); - secure_vector ws; - m_v = m_params->mul(m_v, m_params->R2(), ws); - } - } - -void Montgomery_Int::fix_size() - { - const size_t p_words = m_params->p_words(); - - if(m_v.sig_words() > p_words) - throw Internal_Error("Montgomery_Int::fix_size v too large"); - - secure_vector& w = m_v.get_word_vector(); - - if(w.size() != p_words) - { - w.resize(p_words); - w.shrink_to_fit(); - } - } - -bool Montgomery_Int::operator==(const Montgomery_Int& other) const - { - return m_v == other.m_v && m_params->p() == other.m_params->p(); - } - -std::vector Montgomery_Int::serialize() const - { - std::vector v(size()); - BigInt::encode_1363(v.data(), v.size(), value()); - return v; - } - -size_t Montgomery_Int::size() const - { - return m_params->p().bytes(); - } - -bool Montgomery_Int::is_one() const - { - return m_v == m_params->R1(); - } - -bool Montgomery_Int::is_zero() const - { - return m_v.is_zero(); - } - -BigInt Montgomery_Int::value() const - { - secure_vector ws; - return m_params->redc(m_v, ws); - } - -Montgomery_Int Montgomery_Int::operator+(const Montgomery_Int& other) const - { - secure_vector ws; - BigInt z = m_v; - z.mod_add(other.m_v, m_params->p(), ws); - return Montgomery_Int(m_params, z, false); - } - -Montgomery_Int Montgomery_Int::operator-(const Montgomery_Int& other) const - { - secure_vector ws; - BigInt z = m_v; - z.mod_sub(other.m_v, m_params->p(), ws); - return Montgomery_Int(m_params, z, false); - } - -Montgomery_Int& Montgomery_Int::operator+=(const Montgomery_Int& other) - { - secure_vector ws; - return this->add(other, ws); - } - -Montgomery_Int& Montgomery_Int::add(const Montgomery_Int& other, secure_vector& ws) - { - m_v.mod_add(other.m_v, m_params->p(), ws); - return (*this); - } - -Montgomery_Int& Montgomery_Int::operator-=(const Montgomery_Int& other) - { - secure_vector ws; - return this->sub(other, ws); - } - -Montgomery_Int& Montgomery_Int::sub(const Montgomery_Int& other, secure_vector& ws) - { - m_v.mod_sub(other.m_v, m_params->p(), ws); - return (*this); - } - -Montgomery_Int Montgomery_Int::operator*(const Montgomery_Int& other) const - { - secure_vector ws; - return Montgomery_Int(m_params, m_params->mul(m_v, other.m_v, ws), false); - } - -Montgomery_Int Montgomery_Int::mul(const Montgomery_Int& other, - secure_vector& ws) const - { - return Montgomery_Int(m_params, m_params->mul(m_v, other.m_v, ws), false); - } - -Montgomery_Int& Montgomery_Int::mul_by(const Montgomery_Int& other, - secure_vector& ws) - { - m_params->mul_by(m_v, other.m_v, ws); - return (*this); - } - -Montgomery_Int& Montgomery_Int::mul_by(const secure_vector& other, - secure_vector& ws) - { - m_params->mul_by(m_v, other, ws); - return (*this); - } - -Montgomery_Int& Montgomery_Int::operator*=(const Montgomery_Int& other) - { - secure_vector ws; - return mul_by(other, ws); - } - -Montgomery_Int& Montgomery_Int::operator*=(const secure_vector& other) - { - secure_vector ws; - return mul_by(other, ws); - } - -Montgomery_Int& Montgomery_Int::square_this_n_times(secure_vector& ws, size_t n) - { - for(size_t i = 0; i != n; ++i) - m_params->square_this(m_v, ws); - return (*this); - } - -Montgomery_Int& Montgomery_Int::square_this(secure_vector& ws) - { - m_params->square_this(m_v, ws); - return (*this); - } - -Montgomery_Int Montgomery_Int::square(secure_vector& ws) const - { - return Montgomery_Int(m_params, m_params->sqr(m_v, ws), false); - } - -Montgomery_Int Montgomery_Int::multiplicative_inverse() const - { - secure_vector ws; - const BigInt iv = m_params->mul(m_params->inv_mod_p(m_v), m_params->R3(), ws); - return Montgomery_Int(m_params, iv, false); - } - -Montgomery_Int Montgomery_Int::additive_inverse() const - { - return Montgomery_Int(m_params, m_params->p()) - (*this); - } - -Montgomery_Int& Montgomery_Int::mul_by_2(secure_vector& ws) - { - m_v.mod_mul(2, m_params->p(), ws); - return (*this); - } - -Montgomery_Int& Montgomery_Int::mul_by_3(secure_vector& ws) - { - m_v.mod_mul(3, m_params->p(), ws); - return (*this); - } - -Montgomery_Int& Montgomery_Int::mul_by_4(secure_vector& ws) - { - m_v.mod_mul(4, m_params->p(), ws); - return (*this); - } - -Montgomery_Int& Montgomery_Int::mul_by_8(secure_vector& ws) - { - m_v.mod_mul(8, m_params->p(), ws); - return (*this); - } - + const BigInt& v, bool redc_needed) + : m_params(params) { + if (redc_needed == false) { + m_v = v; + } else { + BOTAN_ASSERT_NOMSG(m_v < m_params->p()); + secure_vector ws; + m_v = m_params->mul(v, m_params->R2(), ws); + } } -/* -* Montgomery Exponentiation -* (C) 1999-2010,2012,2018 Jack Lloyd -* 2016 Matthias Gierlings -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +Montgomery_Int::Montgomery_Int(std::shared_ptr params, + const uint8_t bits[], size_t len, bool redc_needed) + : m_params(params), m_v(bits, len) { + if (redc_needed) { + BOTAN_ASSERT_NOMSG(m_v < m_params->p()); + secure_vector ws; + m_v = m_params->mul(m_v, m_params->R2(), ws); + } +} + +Montgomery_Int::Montgomery_Int(std::shared_ptr params, const word words[], + size_t len, bool redc_needed) + : m_params(params), m_v(words, len) { + if (redc_needed) { + BOTAN_ASSERT_NOMSG(m_v < m_params->p()); + secure_vector ws; + m_v = m_params->mul(m_v, m_params->R2(), ws); + } +} + +void Montgomery_Int::fix_size() { + const size_t p_words = m_params->p_words(); + + if (m_v.sig_words() > p_words) throw Internal_Error("Montgomery_Int::fix_size v too large"); + + secure_vector& w = m_v.get_word_vector(); + + if (w.size() != p_words) { + w.resize(p_words); + w.shrink_to_fit(); + } +} + +bool Montgomery_Int::operator==(const Montgomery_Int& other) const { + return m_v == other.m_v && m_params->p() == other.m_params->p(); +} + +std::vector Montgomery_Int::serialize() const { + std::vector v(size()); + BigInt::encode_1363(v.data(), v.size(), value()); + return v; +} + +size_t Montgomery_Int::size() const { return m_params->p().bytes(); } + +bool Montgomery_Int::is_one() const { return m_v == m_params->R1(); } + +bool Montgomery_Int::is_zero() const { return m_v.is_zero(); } + +BigInt Montgomery_Int::value() const { + secure_vector ws; + return m_params->redc(m_v, ws); +} + +Montgomery_Int Montgomery_Int::operator+(const Montgomery_Int& other) const { + secure_vector ws; + BigInt z = m_v; + z.mod_add(other.m_v, m_params->p(), ws); + return Montgomery_Int(m_params, z, false); +} + +Montgomery_Int Montgomery_Int::operator-(const Montgomery_Int& other) const { + secure_vector ws; + BigInt z = m_v; + z.mod_sub(other.m_v, m_params->p(), ws); + return Montgomery_Int(m_params, z, false); +} + +Montgomery_Int& Montgomery_Int::operator+=(const Montgomery_Int& other) { + secure_vector ws; + return this->add(other, ws); +} + +Montgomery_Int& Montgomery_Int::add(const Montgomery_Int& other, secure_vector& ws) { + m_v.mod_add(other.m_v, m_params->p(), ws); + return (*this); +} + +Montgomery_Int& Montgomery_Int::operator-=(const Montgomery_Int& other) { + secure_vector ws; + return this->sub(other, ws); +} + +Montgomery_Int& Montgomery_Int::sub(const Montgomery_Int& other, secure_vector& ws) { + m_v.mod_sub(other.m_v, m_params->p(), ws); + return (*this); +} + +Montgomery_Int Montgomery_Int::operator*(const Montgomery_Int& other) const { + secure_vector ws; + return Montgomery_Int(m_params, m_params->mul(m_v, other.m_v, ws), false); +} + +Montgomery_Int Montgomery_Int::mul(const Montgomery_Int& other, secure_vector& ws) const { + return Montgomery_Int(m_params, m_params->mul(m_v, other.m_v, ws), false); +} + +Montgomery_Int& Montgomery_Int::mul_by(const Montgomery_Int& other, secure_vector& ws) { + m_params->mul_by(m_v, other.m_v, ws); + return (*this); +} + +Montgomery_Int& Montgomery_Int::mul_by(const secure_vector& other, secure_vector& ws) { + m_params->mul_by(m_v, other, ws); + return (*this); +} + +Montgomery_Int& Montgomery_Int::operator*=(const Montgomery_Int& other) { + secure_vector ws; + return mul_by(other, ws); +} + +Montgomery_Int& Montgomery_Int::operator*=(const secure_vector& other) { + secure_vector ws; + return mul_by(other, ws); +} + +Montgomery_Int& Montgomery_Int::square_this_n_times(secure_vector& ws, size_t n) { + for (size_t i = 0; i != n; ++i) m_params->square_this(m_v, ws); + return (*this); +} + +Montgomery_Int& Montgomery_Int::square_this(secure_vector& ws) { + m_params->square_this(m_v, ws); + return (*this); +} + +Montgomery_Int Montgomery_Int::square(secure_vector& ws) const { + return Montgomery_Int(m_params, m_params->sqr(m_v, ws), false); +} + +Montgomery_Int Montgomery_Int::multiplicative_inverse() const { + secure_vector ws; + const BigInt iv = m_params->mul(m_params->inv_mod_p(m_v), m_params->R3(), ws); + return Montgomery_Int(m_params, iv, false); +} + +Montgomery_Int Montgomery_Int::additive_inverse() const { + return Montgomery_Int(m_params, m_params->p()) - (*this); +} + +Montgomery_Int& Montgomery_Int::mul_by_2(secure_vector& ws) { + m_v.mod_mul(2, m_params->p(), ws); + return (*this); +} + +Montgomery_Int& Montgomery_Int::mul_by_3(secure_vector& ws) { + m_v.mod_mul(3, m_params->p(), ws); + return (*this); +} + +Montgomery_Int& Montgomery_Int::mul_by_4(secure_vector& ws) { + m_v.mod_mul(4, m_params->p(), ws); + return (*this); +} + +Montgomery_Int& Montgomery_Int::mul_by_8(secure_vector& ws) { + m_v.mod_mul(8, m_params->p(), ws); + return (*this); +} + +} // namespace Botan +/* + * Montgomery Exponentiation + * (C) 1999-2010,2012,2018 Jack Lloyd + * 2016 Matthias Gierlings + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -class Montgomery_Exponentation_State - { +class Montgomery_Exponentation_State { public: - Montgomery_Exponentation_State(std::shared_ptr params, - const BigInt& g, - size_t window_bits, - bool const_time); + Montgomery_Exponentation_State(std::shared_ptr params, const BigInt& g, + size_t window_bits, bool const_time); - BigInt exponentiation(const BigInt& k, size_t max_k_bits) const; + BigInt exponentiation(const BigInt& k, size_t max_k_bits) const; + + BigInt exponentiation_vartime(const BigInt& k) const; - BigInt exponentiation_vartime(const BigInt& k) const; private: - std::shared_ptr m_params; - std::vector m_g; - size_t m_window_bits; - bool m_const_time; - }; + std::shared_ptr m_params; + std::vector m_g; + size_t m_window_bits; + bool m_const_time; +}; -Montgomery_Exponentation_State::Montgomery_Exponentation_State(std::shared_ptr params, - const BigInt& g, - size_t window_bits, - bool const_time) : - m_params(params), - m_window_bits(window_bits == 0 ? 4 : window_bits), - m_const_time(const_time) - { - BOTAN_ARG_CHECK(g < m_params->p(), "Montgomery base too big"); +Montgomery_Exponentation_State::Montgomery_Exponentation_State( + std::shared_ptr params, const BigInt& g, size_t window_bits, + bool const_time) + : m_params(params), + m_window_bits(window_bits == 0 ? 4 : window_bits), + m_const_time(const_time) { + BOTAN_ARG_CHECK(g < m_params->p(), "Montgomery base too big"); - if(m_window_bits < 1 || m_window_bits > 12) // really even 8 is too large ... - throw Invalid_Argument("Invalid window bits for Montgomery exponentiation"); + if (m_window_bits < 1 || m_window_bits > 12) // really even 8 is too large ... + throw Invalid_Argument("Invalid window bits for Montgomery exponentiation"); - const size_t window_size = (static_cast(1) << m_window_bits); + const size_t window_size = (static_cast(1) << m_window_bits); - m_g.reserve(window_size); + m_g.reserve(window_size); - m_g.push_back(Montgomery_Int(m_params, m_params->R1(), false)); + m_g.push_back(Montgomery_Int(m_params, m_params->R1(), false)); - m_g.push_back(Montgomery_Int(m_params, g)); + m_g.push_back(Montgomery_Int(m_params, g)); - for(size_t i = 2; i != window_size; ++i) - { - m_g.push_back(m_g[1] * m_g[i - 1]); - } + for (size_t i = 2; i != window_size; ++i) { + m_g.push_back(m_g[1] * m_g[i - 1]); + } - // Resize each element to exactly p words - for(size_t i = 0; i != window_size; ++i) - { - m_g[i].fix_size(); - if(const_time) - m_g[i].const_time_poison(); - } - } + // Resize each element to exactly p words + for (size_t i = 0; i != window_size; ++i) { + m_g[i].fix_size(); + if (const_time) m_g[i].const_time_poison(); + } +} namespace { -void const_time_lookup(secure_vector& output, - const std::vector& g, - size_t nibble) - { - BOTAN_ASSERT_NOMSG(g.size() % 2 == 0); // actually a power of 2 +void const_time_lookup(secure_vector& output, const std::vector& g, + size_t nibble) { + BOTAN_ASSERT_NOMSG(g.size() % 2 == 0); // actually a power of 2 - const size_t words = output.size(); + const size_t words = output.size(); - clear_mem(output.data(), output.size()); + clear_mem(output.data(), output.size()); - for(size_t i = 0; i != g.size(); i += 2) - { - const secure_vector& vec_0 = g[i ].repr().get_word_vector(); - const secure_vector& vec_1 = g[i+1].repr().get_word_vector(); + for (size_t i = 0; i != g.size(); i += 2) { + const secure_vector& vec_0 = g[i].repr().get_word_vector(); + const secure_vector& vec_1 = g[i + 1].repr().get_word_vector(); - BOTAN_ASSERT_NOMSG(vec_0.size() >= words && vec_1.size() >= words); + BOTAN_ASSERT_NOMSG(vec_0.size() >= words && vec_1.size() >= words); - const auto mask_0 = CT::Mask::is_equal(nibble, i); - const auto mask_1 = CT::Mask::is_equal(nibble, i+1); - - for(size_t w = 0; w != words; ++w) - { - output[w] |= mask_0.if_set_return(vec_0[w]); - output[w] |= mask_1.if_set_return(vec_1[w]); - } - } - } + const auto mask_0 = CT::Mask::is_equal(nibble, i); + const auto mask_1 = CT::Mask::is_equal(nibble, i + 1); + for (size_t w = 0; w != words; ++w) { + output[w] |= mask_0.if_set_return(vec_0[w]); + output[w] |= mask_1.if_set_return(vec_1[w]); + } + } } -BigInt Montgomery_Exponentation_State::exponentiation(const BigInt& scalar, size_t max_k_bits) const - { - BOTAN_DEBUG_ASSERT(scalar.bits() <= max_k_bits); - // TODO add a const-time implementation of above assert and use it in release builds +} // namespace - const size_t exp_nibbles = (max_k_bits + m_window_bits - 1) / m_window_bits; +BigInt Montgomery_Exponentation_State::exponentiation(const BigInt& scalar, + size_t max_k_bits) const { + BOTAN_DEBUG_ASSERT(scalar.bits() <= max_k_bits); + // TODO add a const-time implementation of above assert and use it in release builds - if(exp_nibbles == 0) - return 1; + const size_t exp_nibbles = (max_k_bits + m_window_bits - 1) / m_window_bits; - secure_vector e_bits(m_params->p_words()); - secure_vector ws; + if (exp_nibbles == 0) return 1; - const_time_lookup(e_bits, m_g, scalar.get_substring(m_window_bits*(exp_nibbles-1), m_window_bits)); - Montgomery_Int x(m_params, e_bits.data(), e_bits.size(), false); + secure_vector e_bits(m_params->p_words()); + secure_vector ws; - for(size_t i = exp_nibbles - 1; i > 0; --i) - { - x.square_this_n_times(ws, m_window_bits); - const_time_lookup(e_bits, m_g, scalar.get_substring(m_window_bits*(i-1), m_window_bits)); - x.mul_by(e_bits, ws); - } + const_time_lookup(e_bits, m_g, + scalar.get_substring(m_window_bits * (exp_nibbles - 1), m_window_bits)); + Montgomery_Int x(m_params, e_bits.data(), e_bits.size(), false); - x.const_time_unpoison(); - return x.value(); - } + for (size_t i = exp_nibbles - 1; i > 0; --i) { + x.square_this_n_times(ws, m_window_bits); + const_time_lookup(e_bits, m_g, + scalar.get_substring(m_window_bits * (i - 1), m_window_bits)); + x.mul_by(e_bits, ws); + } -BigInt Montgomery_Exponentation_State::exponentiation_vartime(const BigInt& scalar) const - { - BOTAN_ASSERT_NOMSG(m_const_time == false); + x.const_time_unpoison(); + return x.value(); +} - const size_t exp_nibbles = (scalar.bits() + m_window_bits - 1) / m_window_bits; +BigInt Montgomery_Exponentation_State::exponentiation_vartime(const BigInt& scalar) const { + BOTAN_ASSERT_NOMSG(m_const_time == false); - secure_vector ws; + const size_t exp_nibbles = (scalar.bits() + m_window_bits - 1) / m_window_bits; - if(exp_nibbles == 0) - return 1; + secure_vector ws; - Montgomery_Int x = m_g[scalar.get_substring(m_window_bits*(exp_nibbles-1), m_window_bits)]; + if (exp_nibbles == 0) return 1; - for(size_t i = exp_nibbles - 1; i > 0; --i) - { - x.square_this_n_times(ws, m_window_bits); + Montgomery_Int x = m_g[scalar.get_substring(m_window_bits * (exp_nibbles - 1), m_window_bits)]; - const uint32_t nibble = scalar.get_substring(m_window_bits*(i-1), m_window_bits); - if(nibble > 0) - x.mul_by(m_g[nibble], ws); - } + for (size_t i = exp_nibbles - 1; i > 0; --i) { + x.square_this_n_times(ws, m_window_bits); - x.const_time_unpoison(); - return x.value(); - } + const uint32_t nibble = scalar.get_substring(m_window_bits * (i - 1), m_window_bits); + if (nibble > 0) x.mul_by(m_g[nibble], ws); + } -std::shared_ptr -monty_precompute(std::shared_ptr params, - const BigInt& g, - size_t window_bits, - bool const_time) - { - return std::make_shared(params, g, window_bits, const_time); - } + x.const_time_unpoison(); + return x.value(); +} -BigInt monty_execute(const Montgomery_Exponentation_State& precomputed_state, - const BigInt& k, size_t max_k_bits) - { - return precomputed_state.exponentiation(k, max_k_bits); - } +std::shared_ptr monty_precompute( + std::shared_ptr params, const BigInt& g, size_t window_bits, + bool const_time) { + return std::make_shared(params, g, window_bits, + const_time); +} + +BigInt monty_execute(const Montgomery_Exponentation_State& precomputed_state, const BigInt& k, + size_t max_k_bits) { + return precomputed_state.exponentiation(k, max_k_bits); +} BigInt monty_execute_vartime(const Montgomery_Exponentation_State& precomputed_state, - const BigInt& k) - { - return precomputed_state.exponentiation_vartime(k); - } - -BigInt monty_multi_exp(std::shared_ptr params_p, - const BigInt& x_bn, - const BigInt& z1, - const BigInt& y_bn, - const BigInt& z2) - { - if(z1.is_negative() || z2.is_negative()) - throw Invalid_Argument("multi_exponentiate exponents must be positive"); - - const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2); - - secure_vector ws; - - const Montgomery_Int one(params_p, params_p->R1(), false); - //const Montgomery_Int one(params_p, 1); - - const Montgomery_Int x1(params_p, x_bn); - const Montgomery_Int x2 = x1.square(ws); - const Montgomery_Int x3 = x2.mul(x1, ws); - - const Montgomery_Int y1(params_p, y_bn); - const Montgomery_Int y2 = y1.square(ws); - const Montgomery_Int y3 = y2.mul(y1, ws); - - const Montgomery_Int y1x1 = y1.mul(x1, ws); - const Montgomery_Int y1x2 = y1.mul(x2, ws); - const Montgomery_Int y1x3 = y1.mul(x3, ws); - - const Montgomery_Int y2x1 = y2.mul(x1, ws); - const Montgomery_Int y2x2 = y2.mul(x2, ws); - const Montgomery_Int y2x3 = y2.mul(x3, ws); - - const Montgomery_Int y3x1 = y3.mul(x1, ws); - const Montgomery_Int y3x2 = y3.mul(x2, ws); - const Montgomery_Int y3x3 = y3.mul(x3, ws); - - const Montgomery_Int* M[16] = { - &one, - &x1, // 0001 - &x2, // 0010 - &x3, // 0011 - &y1, // 0100 - &y1x1, - &y1x2, - &y1x3, - &y2, // 1000 - &y2x1, - &y2x2, - &y2x3, - &y3, // 1100 - &y3x1, - &y3x2, - &y3x3 - }; - - Montgomery_Int H = one; - - for(size_t i = 0; i != z_bits; i += 2) - { - if(i > 0) - { - H.square_this(ws); - H.square_this(ws); - } - - const uint32_t z1_b = z1.get_substring(z_bits - i - 2, 2); - const uint32_t z2_b = z2.get_substring(z_bits - i - 2, 2); - - const uint32_t z12 = (4*z2_b) + z1_b; - - H.mul_by(*M[z12], ws); - } - - return H.value(); - } - + const BigInt& k) { + return precomputed_state.exponentiation_vartime(k); } -/* -* Fused and Important MP Algorithms -* (C) 1999-2007 Jack Lloyd -* 2016 Matthias Gierlings -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +BigInt monty_multi_exp(std::shared_ptr params_p, const BigInt& x_bn, + const BigInt& z1, const BigInt& y_bn, const BigInt& z2) { + if (z1.is_negative() || z2.is_negative()) + throw Invalid_Argument("multi_exponentiate exponents must be positive"); + const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2); + + secure_vector ws; + + const Montgomery_Int one(params_p, params_p->R1(), false); + // const Montgomery_Int one(params_p, 1); + + const Montgomery_Int x1(params_p, x_bn); + const Montgomery_Int x2 = x1.square(ws); + const Montgomery_Int x3 = x2.mul(x1, ws); + + const Montgomery_Int y1(params_p, y_bn); + const Montgomery_Int y2 = y1.square(ws); + const Montgomery_Int y3 = y2.mul(y1, ws); + + const Montgomery_Int y1x1 = y1.mul(x1, ws); + const Montgomery_Int y1x2 = y1.mul(x2, ws); + const Montgomery_Int y1x3 = y1.mul(x3, ws); + + const Montgomery_Int y2x1 = y2.mul(x1, ws); + const Montgomery_Int y2x2 = y2.mul(x2, ws); + const Montgomery_Int y2x3 = y2.mul(x3, ws); + + const Montgomery_Int y3x1 = y3.mul(x1, ws); + const Montgomery_Int y3x2 = y3.mul(x2, ws); + const Montgomery_Int y3x3 = y3.mul(x3, ws); + + const Montgomery_Int* M[16] = {&one, + &x1, // 0001 + &x2, // 0010 + &x3, // 0011 + &y1, // 0100 + &y1x1, &y1x2, &y1x3, + &y2, // 1000 + &y2x1, &y2x2, &y2x3, + &y3, // 1100 + &y3x1, &y3x2, &y3x3}; + + Montgomery_Int H = one; + + for (size_t i = 0; i != z_bits; i += 2) { + if (i > 0) { + H.square_this(ws); + H.square_this(ws); + } + + const uint32_t z1_b = z1.get_substring(z_bits - i - 2, 2); + const uint32_t z2_b = z2.get_substring(z_bits - i - 2, 2); + + const uint32_t z12 = (4 * z2_b) + z1_b; + + H.mul_by(*M[z12], ws); + } + + return H.value(); +} + +} // namespace Botan + +/* + * Fused and Important MP Algorithms + * (C) 1999-2007 Jack Lloyd + * 2016 Matthias Gierlings + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Square a BigInt -*/ -BigInt square(const BigInt& x) - { - BigInt z = x; - secure_vector ws; - z.square(ws); - return z; - } - -/* -* Multiply-Add Operation -*/ -BigInt mul_add(const BigInt& a, const BigInt& b, const BigInt& c) - { - if(c.is_negative()) - throw Invalid_Argument("mul_add: Third argument must be > 0"); - - BigInt::Sign sign = BigInt::Positive; - if(a.sign() != b.sign()) - sign = BigInt::Negative; - - const size_t a_sw = a.sig_words(); - const size_t b_sw = b.sig_words(); - const size_t c_sw = c.sig_words(); - - BigInt r(sign, std::max(a_sw + b_sw, c_sw) + 1); - secure_vector workspace(r.size()); - - bigint_mul(r.mutable_data(), r.size(), - a.data(), a.size(), a_sw, - b.data(), b.size(), b_sw, - workspace.data(), workspace.size()); - - const size_t r_size = std::max(r.sig_words(), c_sw); - bigint_add2(r.mutable_data(), r_size, c.data(), c_sw); - return r; - } - -/* -* Subtract-Multiply Operation -*/ -BigInt sub_mul(const BigInt& a, const BigInt& b, const BigInt& c) - { - if(a.is_negative() || b.is_negative()) - throw Invalid_Argument("sub_mul: First two arguments must be >= 0"); - - BigInt r = a; - r -= b; - r *= c; - return r; - } - -/* -* Multiply-Subtract Operation -*/ -BigInt mul_sub(const BigInt& a, const BigInt& b, const BigInt& c) - { - if(c.is_negative() || c.is_zero()) - throw Invalid_Argument("mul_sub: Third argument must be > 0"); - - BigInt r = a; - r *= b; - r -= c; - return r; - } - + * Square a BigInt + */ +BigInt square(const BigInt& x) { + BigInt z = x; + secure_vector ws; + z.square(ws); + return z; } -/* -* NIST prime reductions -* (C) 2014,2015,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Multiply-Add Operation + */ +BigInt mul_add(const BigInt& a, const BigInt& b, const BigInt& c) { + if (c.is_negative()) throw Invalid_Argument("mul_add: Third argument must be > 0"); + + BigInt::Sign sign = BigInt::Positive; + if (a.sign() != b.sign()) sign = BigInt::Negative; + + const size_t a_sw = a.sig_words(); + const size_t b_sw = b.sig_words(); + const size_t c_sw = c.sig_words(); + + BigInt r(sign, std::max(a_sw + b_sw, c_sw) + 1); + secure_vector workspace(r.size()); + + bigint_mul(r.mutable_data(), r.size(), a.data(), a.size(), a_sw, b.data(), b.size(), b_sw, + workspace.data(), workspace.size()); + + const size_t r_size = std::max(r.sig_words(), c_sw); + bigint_add2(r.mutable_data(), r_size, c.data(), c_sw); + return r; +} + +/* + * Subtract-Multiply Operation + */ +BigInt sub_mul(const BigInt& a, const BigInt& b, const BigInt& c) { + if (a.is_negative() || b.is_negative()) + throw Invalid_Argument("sub_mul: First two arguments must be >= 0"); + + BigInt r = a; + r -= b; + r *= c; + return r; +} + +/* + * Multiply-Subtract Operation + */ +BigInt mul_sub(const BigInt& a, const BigInt& b, const BigInt& c) { + if (c.is_negative() || c.is_zero()) + throw Invalid_Argument("mul_sub: Third argument must be > 0"); + + BigInt r = a; + r *= b; + r -= c; + return r; +} + +} // namespace Botan +/* + * NIST prime reductions + * (C) 2014,2015,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -const BigInt& prime_p521() - { - static const BigInt p521("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); +const BigInt& prime_p521() { + static const BigInt p521( + "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); - return p521; - } + return p521; +} -void redc_p521(BigInt& x, secure_vector& ws) - { - const size_t p_full_words = 521 / BOTAN_MP_WORD_BITS; - const size_t p_top_bits = 521 % BOTAN_MP_WORD_BITS; - const size_t p_words = p_full_words + 1; +void redc_p521(BigInt& x, secure_vector& ws) { + const size_t p_full_words = 521 / BOTAN_MP_WORD_BITS; + const size_t p_top_bits = 521 % BOTAN_MP_WORD_BITS; + const size_t p_words = p_full_words + 1; #if (BOTAN_MP_WORD_BITS == 64) - static const word p521_words[p_words] = { - 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, - 0x1FF }; + static const word p521_words[p_words] = { + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x1FF}; #else - static const word p521_words[p_words] = { - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0x1FF }; + static const word p521_words[p_words] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x1FF}; #endif - if(ws.size() < p_words + 1) - ws.resize(p_words + 1); + if (ws.size() < p_words + 1) ws.resize(p_words + 1); - clear_mem(ws.data(), ws.size()); - bigint_shr2(ws.data(), x.data(), std::min(x.size(), 2*p_words), p_full_words, p_top_bits); + clear_mem(ws.data(), ws.size()); + bigint_shr2(ws.data(), x.data(), std::min(x.size(), 2 * p_words), p_full_words, p_top_bits); - x.mask_bits(521); - x.grow_to(p_words); + x.mask_bits(521); + x.grow_to(p_words); - // Word-level carry will be zero - word carry = bigint_add3_nc(x.mutable_data(), x.data(), p_words, ws.data(), p_words); - BOTAN_ASSERT_EQUAL(carry, 0, "Final carry in P-521 reduction"); + // Word-level carry will be zero + word carry = bigint_add3_nc(x.mutable_data(), x.data(), p_words, ws.data(), p_words); + BOTAN_ASSERT_EQUAL(carry, 0, "Final carry in P-521 reduction"); - const word top_word = x.word_at(p_full_words); + const word top_word = x.word_at(p_full_words); - /* - * Check if we need to reduce modulo P - * There are two possible cases: - * - The result overflowed past 521 bits, in which case bit 522 will be set - * - The result is exactly 2**521 - 1 - */ - const auto bit_522_set = CT::Mask::expand(top_word >> p_top_bits); + /* + * Check if we need to reduce modulo P + * There are two possible cases: + * - The result overflowed past 521 bits, in which case bit 522 will be set + * - The result is exactly 2**521 - 1 + */ + const auto bit_522_set = CT::Mask::expand(top_word >> p_top_bits); - word and_512 = MP_WORD_MAX; - for(size_t i = 0; i != p_full_words; ++i) - and_512 &= x.word_at(i); - const auto all_512_low_bits_set = CT::Mask::is_equal(and_512, MP_WORD_MAX); - const auto has_p521_top_word = CT::Mask::is_equal(top_word, 0x1FF); - const auto is_p521 = all_512_low_bits_set & has_p521_top_word; + word and_512 = MP_WORD_MAX; + for (size_t i = 0; i != p_full_words; ++i) and_512 &= x.word_at(i); + const auto all_512_low_bits_set = CT::Mask::is_equal(and_512, MP_WORD_MAX); + const auto has_p521_top_word = CT::Mask::is_equal(top_word, 0x1FF); + const auto is_p521 = all_512_low_bits_set & has_p521_top_word; - const auto needs_reduction = is_p521 | bit_522_set; + const auto needs_reduction = is_p521 | bit_522_set; - bigint_cnd_sub(needs_reduction.value(), x.mutable_data(), p521_words, p_words); - } + bigint_cnd_sub(needs_reduction.value(), x.mutable_data(), p521_words, p_words); +} namespace { /** -* Treating this MPI as a sequence of 32-bit words in big-endian -* order, return word i (or 0 if out of range) -*/ -inline uint32_t get_uint32(const BigInt& x, size_t i) - { + * Treating this MPI as a sequence of 32-bit words in big-endian + * order, return word i (or 0 if out of range) + */ +inline uint32_t get_uint32(const BigInt& x, size_t i) { #if (BOTAN_MP_WORD_BITS == 32) - return x.word_at(i); + return x.word_at(i); #else - return static_cast(x.word_at(i/2) >> ((i % 2)*32)); + return static_cast(x.word_at(i / 2) >> ((i % 2) * 32)); #endif - } - -inline void set_words(word x[], size_t i, uint32_t R0, uint32_t R1) - { -#if (BOTAN_MP_WORD_BITS == 32) - x[i] = R0; - x[i+1] = R1; -#else - x[i/2] = (static_cast(R1) << 32) | R0; -#endif - } - } -const BigInt& prime_p192() - { - static const BigInt p192("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); - return p192; - } - -void redc_p192(BigInt& x, secure_vector& ws) - { - BOTAN_UNUSED(ws); - - static const size_t p192_limbs = 192 / BOTAN_MP_WORD_BITS; - - const uint64_t X00 = get_uint32(x, 0); - const uint64_t X01 = get_uint32(x, 1); - const uint64_t X02 = get_uint32(x, 2); - const uint64_t X03 = get_uint32(x, 3); - const uint64_t X04 = get_uint32(x, 4); - const uint64_t X05 = get_uint32(x, 5); - const uint64_t X06 = get_uint32(x, 6); - const uint64_t X07 = get_uint32(x, 7); - const uint64_t X08 = get_uint32(x, 8); - const uint64_t X09 = get_uint32(x, 9); - const uint64_t X10 = get_uint32(x, 10); - const uint64_t X11 = get_uint32(x, 11); - - const uint64_t S0 = X00 + X06 + X10; - const uint64_t S1 = X01 + X07 + X11; - const uint64_t S2 = X02 + X06 + X08 + X10; - const uint64_t S3 = X03 + X07 + X09 + X11; - const uint64_t S4 = X04 + X08 + X10; - const uint64_t S5 = X05 + X09 + X11; - - x.mask_bits(192); - x.resize(p192_limbs + 1); - - word* xw = x.mutable_data(); - - uint64_t S = 0; - uint32_t R0 = 0, R1 = 0; - - S += S0; - R0 = static_cast(S); - S >>= 32; - - S += S1; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 0, R0, R1); - - S += S2; - R0 = static_cast(S); - S >>= 32; - - S += S3; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 2, R0, R1); - - S += S4; - R0 = static_cast(S); - S >>= 32; - - S += S5; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 4, R0, R1); - - // No underflow possible - - /* - This is a table of (i*P-192) % 2**192 for i in 1...3 - */ - static const word p192_mults[3][p192_limbs] = { -#if (BOTAN_MP_WORD_BITS == 64) - {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF}, - {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF}, - {0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF}, +inline void set_words(word x[], size_t i, uint32_t R0, uint32_t R1) { +#if (BOTAN_MP_WORD_BITS == 32) + x[i] = R0; + x[i + 1] = R1; #else - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + x[i / 2] = (static_cast(R1) << 32) | R0; #endif - }; - - CT::unpoison(S); - BOTAN_ASSERT(S <= 2, "Expected overflow"); - - BOTAN_ASSERT_NOMSG(x.size() == p192_limbs + 1); - word borrow = bigint_sub2(x.mutable_data(), p192_limbs + 1, p192_mults[S], p192_limbs); - BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - bigint_cnd_add(borrow, x.mutable_data(), p192_limbs + 1, p192_mults[0], p192_limbs); - } - -const BigInt& prime_p224() - { - static const BigInt p224("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); - return p224; - } - -void redc_p224(BigInt& x, secure_vector& ws) - { - static const size_t p224_limbs = (BOTAN_MP_WORD_BITS == 32) ? 7 : 4; - - BOTAN_UNUSED(ws); - - const int64_t X00 = get_uint32(x, 0); - const int64_t X01 = get_uint32(x, 1); - const int64_t X02 = get_uint32(x, 2); - const int64_t X03 = get_uint32(x, 3); - const int64_t X04 = get_uint32(x, 4); - const int64_t X05 = get_uint32(x, 5); - const int64_t X06 = get_uint32(x, 6); - const int64_t X07 = get_uint32(x, 7); - const int64_t X08 = get_uint32(x, 8); - const int64_t X09 = get_uint32(x, 9); - const int64_t X10 = get_uint32(x, 10); - const int64_t X11 = get_uint32(x, 11); - const int64_t X12 = get_uint32(x, 12); - const int64_t X13 = get_uint32(x, 13); - - // One full copy of P224 is added, so the result is always positive - - const int64_t S0 = 0x00000001 + X00 - X07 - X11; - const int64_t S1 = 0x00000000 + X01 - X08 - X12; - const int64_t S2 = 0x00000000 + X02 - X09 - X13; - const int64_t S3 = 0xFFFFFFFF + X03 + X07 + X11 - X10; - const int64_t S4 = 0xFFFFFFFF + X04 + X08 + X12 - X11; - const int64_t S5 = 0xFFFFFFFF + X05 + X09 + X13 - X12; - const int64_t S6 = 0xFFFFFFFF + X06 + X10 - X13; - - x.mask_bits(224); - x.resize(p224_limbs + 1); - - word* xw = x.mutable_data(); - - int64_t S = 0; - uint32_t R0 = 0, R1 = 0; - - S += S0; - R0 = static_cast(S); - S >>= 32; - - S += S1; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 0, R0, R1); - - S += S2; - R0 = static_cast(S); - S >>= 32; - - S += S3; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 2, R0, R1); - - S += S4; - R0 = static_cast(S); - S >>= 32; - - S += S5; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 4, R0, R1); - - S += S6; - R0 = static_cast(S); - S >>= 32; - - set_words(xw, 6, R0, 0); - - static const word p224_mults[3][p224_limbs] = { -#if (BOTAN_MP_WORD_BITS == 64) - {0x0000000000000001, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, - {0x0000000000000002, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, - {0x0000000000000003, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, -#else - {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0x00000003, 0x00000000, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} -#endif - - }; - - CT::unpoison(S); - BOTAN_ASSERT(S >= 0 && S <= 2, "Expected overflow"); - - BOTAN_ASSERT_NOMSG(x.size() == p224_limbs + 1); - word borrow = bigint_sub2(x.mutable_data(), p224_limbs + 1, p224_mults[S], p224_limbs); - BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - bigint_cnd_add(borrow, x.mutable_data(), p224_limbs + 1, p224_mults[0], p224_limbs); - } - -const BigInt& prime_p256() - { - static const BigInt p256("0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); - return p256; - } - -void redc_p256(BigInt& x, secure_vector& ws) - { - static const size_t p256_limbs = (BOTAN_MP_WORD_BITS == 32) ? 8 : 4; - - BOTAN_UNUSED(ws); - - const int64_t X00 = get_uint32(x, 0); - const int64_t X01 = get_uint32(x, 1); - const int64_t X02 = get_uint32(x, 2); - const int64_t X03 = get_uint32(x, 3); - const int64_t X04 = get_uint32(x, 4); - const int64_t X05 = get_uint32(x, 5); - const int64_t X06 = get_uint32(x, 6); - const int64_t X07 = get_uint32(x, 7); - const int64_t X08 = get_uint32(x, 8); - const int64_t X09 = get_uint32(x, 9); - const int64_t X10 = get_uint32(x, 10); - const int64_t X11 = get_uint32(x, 11); - const int64_t X12 = get_uint32(x, 12); - const int64_t X13 = get_uint32(x, 13); - const int64_t X14 = get_uint32(x, 14); - const int64_t X15 = get_uint32(x, 15); - - // Adds 6 * P-256 to prevent underflow - const int64_t S0 = 0xFFFFFFFA + X00 + X08 + X09 - (X11 + X12 + X13) - X14; - const int64_t S1 = 0xFFFFFFFF + X01 + X09 + X10 - X12 - (X13 + X14 + X15); - const int64_t S2 = 0xFFFFFFFF + X02 + X10 + X11 - (X13 + X14 + X15); - const int64_t S3 = 0x00000005 + X03 + (X11 + X12)*2 + X13 - X15 - X08 - X09; - const int64_t S4 = 0x00000000 + X04 + (X12 + X13)*2 + X14 - X09 - X10; - const int64_t S5 = 0x00000000 + X05 + (X13 + X14)*2 + X15 - X10 - X11; - const int64_t S6 = 0x00000006 + X06 + X13 + X14*3 + X15*2 - X08 - X09; - const int64_t S7 = 0xFFFFFFFA + X07 + X15*3 + X08 - X10 - (X11 + X12 + X13); - - x.mask_bits(256); - x.resize(p256_limbs + 1); - - word* xw = x.mutable_data(); - - int64_t S = 0; - - uint32_t R0 = 0, R1 = 0; - - S += S0; - R0 = static_cast(S); - S >>= 32; - - S += S1; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 0, R0, R1); - - S += S2; - R0 = static_cast(S); - S >>= 32; - - S += S3; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 2, R0, R1); - - S += S4; - R0 = static_cast(S); - S >>= 32; - - S += S5; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 4, R0, R1); - - S += S6; - R0 = static_cast(S); - S >>= 32; - - S += S7; - R1 = static_cast(S); - S >>= 32; - set_words(xw, 6, R0, R1); - - S += 5; // the top digits of 6*P-256 - - /* - This is a table of (i*P-256) % 2**256 for i in 1...10 - */ - static const word p256_mults[11][p256_limbs] = { -#if (BOTAN_MP_WORD_BITS == 64) - {0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000001}, - {0xFFFFFFFFFFFFFFFE, 0x00000001FFFFFFFF, 0x0000000000000000, 0xFFFFFFFE00000002}, - {0xFFFFFFFFFFFFFFFD, 0x00000002FFFFFFFF, 0x0000000000000000, 0xFFFFFFFD00000003}, - {0xFFFFFFFFFFFFFFFC, 0x00000003FFFFFFFF, 0x0000000000000000, 0xFFFFFFFC00000004}, - {0xFFFFFFFFFFFFFFFB, 0x00000004FFFFFFFF, 0x0000000000000000, 0xFFFFFFFB00000005}, - {0xFFFFFFFFFFFFFFFA, 0x00000005FFFFFFFF, 0x0000000000000000, 0xFFFFFFFA00000006}, - {0xFFFFFFFFFFFFFFF9, 0x00000006FFFFFFFF, 0x0000000000000000, 0xFFFFFFF900000007}, - {0xFFFFFFFFFFFFFFF8, 0x00000007FFFFFFFF, 0x0000000000000000, 0xFFFFFFF800000008}, - {0xFFFFFFFFFFFFFFF7, 0x00000008FFFFFFFF, 0x0000000000000000, 0xFFFFFFF700000009}, - {0xFFFFFFFFFFFFFFF6, 0x00000009FFFFFFFF, 0x0000000000000000, 0xFFFFFFF60000000A}, - {0xFFFFFFFFFFFFFFF5, 0x0000000AFFFFFFFF, 0x0000000000000000, 0xFFFFFFF50000000B}, -#else - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF}, - {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE}, - {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD}, - {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC}, - {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB}, - {0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000005, 0x00000000, 0x00000000, 0x00000006, 0xFFFFFFFA}, - {0xFFFFFFF9, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0xFFFFFFF9}, - {0xFFFFFFF8, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000, 0x00000000, 0x00000008, 0xFFFFFFF8}, - {0xFFFFFFF7, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000008, 0x00000000, 0x00000000, 0x00000009, 0xFFFFFFF7}, - {0xFFFFFFF6, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000009, 0x00000000, 0x00000000, 0x0000000A, 0xFFFFFFF6}, - {0xFFFFFFF5, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000A, 0x00000000, 0x00000000, 0x0000000B, 0xFFFFFFF5}, -#endif - }; - - CT::unpoison(S); - BOTAN_ASSERT(S >= 0 && S <= 10, "Expected overflow"); - - BOTAN_ASSERT_NOMSG(x.size() == p256_limbs + 1); - word borrow = bigint_sub2(x.mutable_data(), p256_limbs + 1, p256_mults[S], p256_limbs); - BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - bigint_cnd_add(borrow, x.mutable_data(), p256_limbs + 1, p256_mults[0], p256_limbs); - } - -const BigInt& prime_p384() - { - static const BigInt p384("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"); - return p384; - } - -void redc_p384(BigInt& x, secure_vector& ws) - { - BOTAN_UNUSED(ws); - - static const size_t p384_limbs = (BOTAN_MP_WORD_BITS == 32) ? 12 : 6; - - const int64_t X00 = get_uint32(x, 0); - const int64_t X01 = get_uint32(x, 1); - const int64_t X02 = get_uint32(x, 2); - const int64_t X03 = get_uint32(x, 3); - const int64_t X04 = get_uint32(x, 4); - const int64_t X05 = get_uint32(x, 5); - const int64_t X06 = get_uint32(x, 6); - const int64_t X07 = get_uint32(x, 7); - const int64_t X08 = get_uint32(x, 8); - const int64_t X09 = get_uint32(x, 9); - const int64_t X10 = get_uint32(x, 10); - const int64_t X11 = get_uint32(x, 11); - const int64_t X12 = get_uint32(x, 12); - const int64_t X13 = get_uint32(x, 13); - const int64_t X14 = get_uint32(x, 14); - const int64_t X15 = get_uint32(x, 15); - const int64_t X16 = get_uint32(x, 16); - const int64_t X17 = get_uint32(x, 17); - const int64_t X18 = get_uint32(x, 18); - const int64_t X19 = get_uint32(x, 19); - const int64_t X20 = get_uint32(x, 20); - const int64_t X21 = get_uint32(x, 21); - const int64_t X22 = get_uint32(x, 22); - const int64_t X23 = get_uint32(x, 23); - - // One copy of P-384 is added to prevent underflow - const int64_t S0 = 0xFFFFFFFF + X00 + X12 + X20 + X21 - X23; - const int64_t S1 = 0x00000000 + X01 + X13 + X22 + X23 - X12 - X20; - const int64_t S2 = 0x00000000 + X02 + X14 + X23 - X13 - X21; - const int64_t S3 = 0xFFFFFFFF + X03 + X12 + X15 + X20 + X21 - X14 - X22 - X23; - const int64_t S4 = 0xFFFFFFFE + X04 + X12 + X13 + X16 + X20 + X21*2 + X22 - X15 - X23*2; - const int64_t S5 = 0xFFFFFFFF + X05 + X13 + X14 + X17 + X21 + X22*2 + X23 - X16; - const int64_t S6 = 0xFFFFFFFF + X06 + X14 + X15 + X18 + X22 + X23*2 - X17; - const int64_t S7 = 0xFFFFFFFF + X07 + X15 + X16 + X19 + X23 - X18; - const int64_t S8 = 0xFFFFFFFF + X08 + X16 + X17 + X20 - X19; - const int64_t S9 = 0xFFFFFFFF + X09 + X17 + X18 + X21 - X20; - const int64_t SA = 0xFFFFFFFF + X10 + X18 + X19 + X22 - X21; - const int64_t SB = 0xFFFFFFFF + X11 + X19 + X20 + X23 - X22; - - x.mask_bits(384); - x.resize(p384_limbs + 1); - - word* xw = x.mutable_data(); - - int64_t S = 0; - - uint32_t R0 = 0, R1 = 0; - - S += S0; - R0 = static_cast(S); - S >>= 32; - - S += S1; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 0, R0, R1); - - S += S2; - R0 = static_cast(S); - S >>= 32; - - S += S3; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 2, R0, R1); - - S += S4; - R0 = static_cast(S); - S >>= 32; - - S += S5; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 4, R0, R1); - - S += S6; - R0 = static_cast(S); - S >>= 32; - - S += S7; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 6, R0, R1); - - S += S8; - R0 = static_cast(S); - S >>= 32; - - S += S9; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 8, R0, R1); - - S += SA; - R0 = static_cast(S); - S >>= 32; - - S += SB; - R1 = static_cast(S); - S >>= 32; - - set_words(xw, 10, R0, R1); - - /* - This is a table of (i*P-384) % 2**384 for i in 1...4 - */ - static const word p384_mults[5][p384_limbs] = { -#if (BOTAN_MP_WORD_BITS == 64) - {0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - {0x00000001FFFFFFFE, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - {0x00000002FFFFFFFD, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - {0x00000003FFFFFFFC, 0xFFFFFFFC00000000, 0xFFFFFFFFFFFFFFFB, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - {0x00000004FFFFFFFB, 0xFFFFFFFB00000000, 0xFFFFFFFFFFFFFFFA, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - -#else - {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, -#endif - }; - - CT::unpoison(S); - BOTAN_ASSERT(S >= 0 && S <= 4, "Expected overflow"); - - BOTAN_ASSERT_NOMSG(x.size() == p384_limbs + 1); - word borrow = bigint_sub2(x.mutable_data(), p384_limbs + 1, p384_mults[S], p384_limbs); - BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); - bigint_cnd_add(borrow, x.mutable_data(), p384_limbs + 1, p384_mults[0], p384_limbs); - } - } + +} // namespace + +const BigInt& prime_p192() { + static const BigInt p192("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); + return p192; +} + +void redc_p192(BigInt& x, secure_vector& ws) { + BOTAN_UNUSED(ws); + + static const size_t p192_limbs = 192 / BOTAN_MP_WORD_BITS; + + const uint64_t X00 = get_uint32(x, 0); + const uint64_t X01 = get_uint32(x, 1); + const uint64_t X02 = get_uint32(x, 2); + const uint64_t X03 = get_uint32(x, 3); + const uint64_t X04 = get_uint32(x, 4); + const uint64_t X05 = get_uint32(x, 5); + const uint64_t X06 = get_uint32(x, 6); + const uint64_t X07 = get_uint32(x, 7); + const uint64_t X08 = get_uint32(x, 8); + const uint64_t X09 = get_uint32(x, 9); + const uint64_t X10 = get_uint32(x, 10); + const uint64_t X11 = get_uint32(x, 11); + + const uint64_t S0 = X00 + X06 + X10; + const uint64_t S1 = X01 + X07 + X11; + const uint64_t S2 = X02 + X06 + X08 + X10; + const uint64_t S3 = X03 + X07 + X09 + X11; + const uint64_t S4 = X04 + X08 + X10; + const uint64_t S5 = X05 + X09 + X11; + + x.mask_bits(192); + x.resize(p192_limbs + 1); + + word* xw = x.mutable_data(); + + uint64_t S = 0; + uint32_t R0 = 0, R1 = 0; + + S += S0; + R0 = static_cast(S); + S >>= 32; + + S += S1; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 0, R0, R1); + + S += S2; + R0 = static_cast(S); + S >>= 32; + + S += S3; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 2, R0, R1); + + S += S4; + R0 = static_cast(S); + S >>= 32; + + S += S5; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 4, R0, R1); + + // No underflow possible + + /* + This is a table of (i*P-192) % 2**192 for i in 1...3 + */ + static const word p192_mults[3][p192_limbs] = { +#if (BOTAN_MP_WORD_BITS == 64) + {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF}, + {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF}, + {0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF}, +#else + {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, +#endif + }; + + CT::unpoison(S); + BOTAN_ASSERT(S <= 2, "Expected overflow"); + + BOTAN_ASSERT_NOMSG(x.size() == p192_limbs + 1); + word borrow = bigint_sub2(x.mutable_data(), p192_limbs + 1, p192_mults[S], p192_limbs); + BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); + bigint_cnd_add(borrow, x.mutable_data(), p192_limbs + 1, p192_mults[0], p192_limbs); +} + +const BigInt& prime_p224() { + static const BigInt p224("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); + return p224; +} + +void redc_p224(BigInt& x, secure_vector& ws) { + static const size_t p224_limbs = (BOTAN_MP_WORD_BITS == 32) ? 7 : 4; + + BOTAN_UNUSED(ws); + + const int64_t X00 = get_uint32(x, 0); + const int64_t X01 = get_uint32(x, 1); + const int64_t X02 = get_uint32(x, 2); + const int64_t X03 = get_uint32(x, 3); + const int64_t X04 = get_uint32(x, 4); + const int64_t X05 = get_uint32(x, 5); + const int64_t X06 = get_uint32(x, 6); + const int64_t X07 = get_uint32(x, 7); + const int64_t X08 = get_uint32(x, 8); + const int64_t X09 = get_uint32(x, 9); + const int64_t X10 = get_uint32(x, 10); + const int64_t X11 = get_uint32(x, 11); + const int64_t X12 = get_uint32(x, 12); + const int64_t X13 = get_uint32(x, 13); + + // One full copy of P224 is added, so the result is always positive + + const int64_t S0 = 0x00000001 + X00 - X07 - X11; + const int64_t S1 = 0x00000000 + X01 - X08 - X12; + const int64_t S2 = 0x00000000 + X02 - X09 - X13; + const int64_t S3 = 0xFFFFFFFF + X03 + X07 + X11 - X10; + const int64_t S4 = 0xFFFFFFFF + X04 + X08 + X12 - X11; + const int64_t S5 = 0xFFFFFFFF + X05 + X09 + X13 - X12; + const int64_t S6 = 0xFFFFFFFF + X06 + X10 - X13; + + x.mask_bits(224); + x.resize(p224_limbs + 1); + + word* xw = x.mutable_data(); + + int64_t S = 0; + uint32_t R0 = 0, R1 = 0; + + S += S0; + R0 = static_cast(S); + S >>= 32; + + S += S1; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 0, R0, R1); + + S += S2; + R0 = static_cast(S); + S >>= 32; + + S += S3; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 2, R0, R1); + + S += S4; + R0 = static_cast(S); + S >>= 32; + + S += S5; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 4, R0, R1); + + S += S6; + R0 = static_cast(S); + S >>= 32; + + set_words(xw, 6, R0, 0); + + static const word p224_mults[3][p224_limbs] = { +#if (BOTAN_MP_WORD_BITS == 64) + {0x0000000000000001, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, + {0x0000000000000002, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, + {0x0000000000000003, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, +#else + {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0x00000003, 0x00000000, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +#endif + + }; + + CT::unpoison(S); + BOTAN_ASSERT(S >= 0 && S <= 2, "Expected overflow"); + + BOTAN_ASSERT_NOMSG(x.size() == p224_limbs + 1); + word borrow = bigint_sub2(x.mutable_data(), p224_limbs + 1, p224_mults[S], p224_limbs); + BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); + bigint_cnd_add(borrow, x.mutable_data(), p224_limbs + 1, p224_mults[0], p224_limbs); +} + +const BigInt& prime_p256() { + static const BigInt p256("0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); + return p256; +} + +void redc_p256(BigInt& x, secure_vector& ws) { + static const size_t p256_limbs = (BOTAN_MP_WORD_BITS == 32) ? 8 : 4; + + BOTAN_UNUSED(ws); + + const int64_t X00 = get_uint32(x, 0); + const int64_t X01 = get_uint32(x, 1); + const int64_t X02 = get_uint32(x, 2); + const int64_t X03 = get_uint32(x, 3); + const int64_t X04 = get_uint32(x, 4); + const int64_t X05 = get_uint32(x, 5); + const int64_t X06 = get_uint32(x, 6); + const int64_t X07 = get_uint32(x, 7); + const int64_t X08 = get_uint32(x, 8); + const int64_t X09 = get_uint32(x, 9); + const int64_t X10 = get_uint32(x, 10); + const int64_t X11 = get_uint32(x, 11); + const int64_t X12 = get_uint32(x, 12); + const int64_t X13 = get_uint32(x, 13); + const int64_t X14 = get_uint32(x, 14); + const int64_t X15 = get_uint32(x, 15); + + // Adds 6 * P-256 to prevent underflow + const int64_t S0 = 0xFFFFFFFA + X00 + X08 + X09 - (X11 + X12 + X13) - X14; + const int64_t S1 = 0xFFFFFFFF + X01 + X09 + X10 - X12 - (X13 + X14 + X15); + const int64_t S2 = 0xFFFFFFFF + X02 + X10 + X11 - (X13 + X14 + X15); + const int64_t S3 = 0x00000005 + X03 + (X11 + X12) * 2 + X13 - X15 - X08 - X09; + const int64_t S4 = 0x00000000 + X04 + (X12 + X13) * 2 + X14 - X09 - X10; + const int64_t S5 = 0x00000000 + X05 + (X13 + X14) * 2 + X15 - X10 - X11; + const int64_t S6 = 0x00000006 + X06 + X13 + X14 * 3 + X15 * 2 - X08 - X09; + const int64_t S7 = 0xFFFFFFFA + X07 + X15 * 3 + X08 - X10 - (X11 + X12 + X13); + + x.mask_bits(256); + x.resize(p256_limbs + 1); + + word* xw = x.mutable_data(); + + int64_t S = 0; + + uint32_t R0 = 0, R1 = 0; + + S += S0; + R0 = static_cast(S); + S >>= 32; + + S += S1; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 0, R0, R1); + + S += S2; + R0 = static_cast(S); + S >>= 32; + + S += S3; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 2, R0, R1); + + S += S4; + R0 = static_cast(S); + S >>= 32; + + S += S5; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 4, R0, R1); + + S += S6; + R0 = static_cast(S); + S >>= 32; + + S += S7; + R1 = static_cast(S); + S >>= 32; + set_words(xw, 6, R0, R1); + + S += 5; // the top digits of 6*P-256 + + /* + This is a table of (i*P-256) % 2**256 for i in 1...10 + */ + static const word p256_mults[11][p256_limbs] = { +#if (BOTAN_MP_WORD_BITS == 64) + {0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000001}, + {0xFFFFFFFFFFFFFFFE, 0x00000001FFFFFFFF, 0x0000000000000000, 0xFFFFFFFE00000002}, + {0xFFFFFFFFFFFFFFFD, 0x00000002FFFFFFFF, 0x0000000000000000, 0xFFFFFFFD00000003}, + {0xFFFFFFFFFFFFFFFC, 0x00000003FFFFFFFF, 0x0000000000000000, 0xFFFFFFFC00000004}, + {0xFFFFFFFFFFFFFFFB, 0x00000004FFFFFFFF, 0x0000000000000000, 0xFFFFFFFB00000005}, + {0xFFFFFFFFFFFFFFFA, 0x00000005FFFFFFFF, 0x0000000000000000, 0xFFFFFFFA00000006}, + {0xFFFFFFFFFFFFFFF9, 0x00000006FFFFFFFF, 0x0000000000000000, 0xFFFFFFF900000007}, + {0xFFFFFFFFFFFFFFF8, 0x00000007FFFFFFFF, 0x0000000000000000, 0xFFFFFFF800000008}, + {0xFFFFFFFFFFFFFFF7, 0x00000008FFFFFFFF, 0x0000000000000000, 0xFFFFFFF700000009}, + {0xFFFFFFFFFFFFFFF6, 0x00000009FFFFFFFF, 0x0000000000000000, 0xFFFFFFF60000000A}, + {0xFFFFFFFFFFFFFFF5, 0x0000000AFFFFFFFF, 0x0000000000000000, 0xFFFFFFF50000000B}, +#else + {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0xFFFFFFFF}, + {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0x00000002, + 0xFFFFFFFE}, + {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00000000, 0x00000000, 0x00000003, + 0xFFFFFFFD}, + {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, 0x00000000, 0x00000000, 0x00000004, + 0xFFFFFFFC}, + {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, 0x00000000, 0x00000000, 0x00000005, + 0xFFFFFFFB}, + {0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000005, 0x00000000, 0x00000000, 0x00000006, + 0xFFFFFFFA}, + {0xFFFFFFF9, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000006, 0x00000000, 0x00000000, 0x00000007, + 0xFFFFFFF9}, + {0xFFFFFFF8, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000, 0x00000000, 0x00000008, + 0xFFFFFFF8}, + {0xFFFFFFF7, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000008, 0x00000000, 0x00000000, 0x00000009, + 0xFFFFFFF7}, + {0xFFFFFFF6, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000009, 0x00000000, 0x00000000, 0x0000000A, + 0xFFFFFFF6}, + {0xFFFFFFF5, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000A, 0x00000000, 0x00000000, 0x0000000B, + 0xFFFFFFF5}, +#endif + }; + + CT::unpoison(S); + BOTAN_ASSERT(S >= 0 && S <= 10, "Expected overflow"); + + BOTAN_ASSERT_NOMSG(x.size() == p256_limbs + 1); + word borrow = bigint_sub2(x.mutable_data(), p256_limbs + 1, p256_mults[S], p256_limbs); + BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); + bigint_cnd_add(borrow, x.mutable_data(), p256_limbs + 1, p256_mults[0], p256_limbs); +} + +const BigInt& prime_p384() { + static const BigInt p384( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000" + "FFFFFFFF"); + return p384; +} + +void redc_p384(BigInt& x, secure_vector& ws) { + BOTAN_UNUSED(ws); + + static const size_t p384_limbs = (BOTAN_MP_WORD_BITS == 32) ? 12 : 6; + + const int64_t X00 = get_uint32(x, 0); + const int64_t X01 = get_uint32(x, 1); + const int64_t X02 = get_uint32(x, 2); + const int64_t X03 = get_uint32(x, 3); + const int64_t X04 = get_uint32(x, 4); + const int64_t X05 = get_uint32(x, 5); + const int64_t X06 = get_uint32(x, 6); + const int64_t X07 = get_uint32(x, 7); + const int64_t X08 = get_uint32(x, 8); + const int64_t X09 = get_uint32(x, 9); + const int64_t X10 = get_uint32(x, 10); + const int64_t X11 = get_uint32(x, 11); + const int64_t X12 = get_uint32(x, 12); + const int64_t X13 = get_uint32(x, 13); + const int64_t X14 = get_uint32(x, 14); + const int64_t X15 = get_uint32(x, 15); + const int64_t X16 = get_uint32(x, 16); + const int64_t X17 = get_uint32(x, 17); + const int64_t X18 = get_uint32(x, 18); + const int64_t X19 = get_uint32(x, 19); + const int64_t X20 = get_uint32(x, 20); + const int64_t X21 = get_uint32(x, 21); + const int64_t X22 = get_uint32(x, 22); + const int64_t X23 = get_uint32(x, 23); + + // One copy of P-384 is added to prevent underflow + const int64_t S0 = 0xFFFFFFFF + X00 + X12 + X20 + X21 - X23; + const int64_t S1 = 0x00000000 + X01 + X13 + X22 + X23 - X12 - X20; + const int64_t S2 = 0x00000000 + X02 + X14 + X23 - X13 - X21; + const int64_t S3 = 0xFFFFFFFF + X03 + X12 + X15 + X20 + X21 - X14 - X22 - X23; + const int64_t S4 = 0xFFFFFFFE + X04 + X12 + X13 + X16 + X20 + X21 * 2 + X22 - X15 - X23 * 2; + const int64_t S5 = 0xFFFFFFFF + X05 + X13 + X14 + X17 + X21 + X22 * 2 + X23 - X16; + const int64_t S6 = 0xFFFFFFFF + X06 + X14 + X15 + X18 + X22 + X23 * 2 - X17; + const int64_t S7 = 0xFFFFFFFF + X07 + X15 + X16 + X19 + X23 - X18; + const int64_t S8 = 0xFFFFFFFF + X08 + X16 + X17 + X20 - X19; + const int64_t S9 = 0xFFFFFFFF + X09 + X17 + X18 + X21 - X20; + const int64_t SA = 0xFFFFFFFF + X10 + X18 + X19 + X22 - X21; + const int64_t SB = 0xFFFFFFFF + X11 + X19 + X20 + X23 - X22; + + x.mask_bits(384); + x.resize(p384_limbs + 1); + + word* xw = x.mutable_data(); + + int64_t S = 0; + + uint32_t R0 = 0, R1 = 0; + + S += S0; + R0 = static_cast(S); + S >>= 32; + + S += S1; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 0, R0, R1); + + S += S2; + R0 = static_cast(S); + S >>= 32; + + S += S3; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 2, R0, R1); + + S += S4; + R0 = static_cast(S); + S >>= 32; + + S += S5; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 4, R0, R1); + + S += S6; + R0 = static_cast(S); + S >>= 32; + + S += S7; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 6, R0, R1); + + S += S8; + R0 = static_cast(S); + S >>= 32; + + S += S9; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 8, R0, R1); + + S += SA; + R0 = static_cast(S); + S >>= 32; + + S += SB; + R1 = static_cast(S); + S >>= 32; + + set_words(xw, 10, R0, R1); + + /* + This is a table of (i*P-384) % 2**384 for i in 1...4 + */ + static const word p384_mults[5][p384_limbs] = { +#if (BOTAN_MP_WORD_BITS == 64) + {0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x00000001FFFFFFFE, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x00000002FFFFFFFD, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x00000003FFFFFFFC, 0xFFFFFFFC00000000, 0xFFFFFFFFFFFFFFFB, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x00000004FFFFFFFB, 0xFFFFFFFB00000000, 0xFFFFFFFFFFFFFFFA, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + +#else + {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, +#endif + }; + + CT::unpoison(S); + BOTAN_ASSERT(S >= 0 && S <= 4, "Expected overflow"); + + BOTAN_ASSERT_NOMSG(x.size() == p384_limbs + 1); + word borrow = bigint_sub2(x.mutable_data(), p384_limbs + 1, p384_mults[S], p384_limbs); + BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1); + bigint_cnd_add(borrow, x.mutable_data(), p384_limbs + 1, p384_mults[0], p384_limbs); +} + +} // namespace Botan /* -* Number Theory Functions -* (C) 1999-2011,2016,2018,2019 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Number Theory Functions + * (C) 1999-2011,2016,2018,2019 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Return the number of 0 bits at the end of n -*/ -size_t low_zero_bits(const BigInt& n) - { - size_t low_zero = 0; + * Return the number of 0 bits at the end of n + */ +size_t low_zero_bits(const BigInt& n) { + size_t low_zero = 0; - if(n.is_positive() && n.is_nonzero()) - { - for(size_t i = 0; i != n.size(); ++i) - { - const word x = n.word_at(i); + if (n.is_positive() && n.is_nonzero()) { + for (size_t i = 0; i != n.size(); ++i) { + const word x = n.word_at(i); - if(x) - { - low_zero += ctz(x); - break; - } - else - low_zero += BOTAN_MP_WORD_BITS; - } - } + if (x) { + low_zero += ctz(x); + break; + } else + low_zero += BOTAN_MP_WORD_BITS; + } + } - return low_zero; - } + return low_zero; +} /* -* Calculate the GCD -*/ -BigInt gcd(const BigInt& a, const BigInt& b) - { - if(a.is_zero() || b.is_zero()) - return 0; - if(a == 1 || b == 1) - return 1; + * Calculate the GCD + */ +BigInt gcd(const BigInt& a, const BigInt& b) { + if (a.is_zero() || b.is_zero()) return 0; + if (a == 1 || b == 1) return 1; - BigInt X[2] = { a, b }; - X[0].set_sign(BigInt::Positive); - X[1].set_sign(BigInt::Positive); + BigInt X[2] = {a, b}; + X[0].set_sign(BigInt::Positive); + X[1].set_sign(BigInt::Positive); - const size_t shift = std::min(low_zero_bits(X[0]), low_zero_bits(X[1])); + const size_t shift = std::min(low_zero_bits(X[0]), low_zero_bits(X[1])); - X[0] >>= shift; - X[1] >>= shift; + X[0] >>= shift; + X[1] >>= shift; - while(X[0].is_nonzero()) - { - X[0] >>= low_zero_bits(X[0]); - X[1] >>= low_zero_bits(X[1]); + while (X[0].is_nonzero()) { + X[0] >>= low_zero_bits(X[0]); + X[1] >>= low_zero_bits(X[1]); - const uint8_t sel = static_cast(X[0] >= X[1]); + const uint8_t sel = static_cast(X[0] >= X[1]); - X[sel^1] -= X[sel]; - X[sel^1] >>= 1; - } + X[sel ^ 1] -= X[sel]; + X[sel ^ 1] >>= 1; + } - return (X[1] << shift); - } + return (X[1] << shift); +} /* -* Calculate the LCM -*/ -BigInt lcm(const BigInt& a, const BigInt& b) - { - return ct_divide(a * b, gcd(a, b)); - } + * Calculate the LCM + */ +BigInt lcm(const BigInt& a, const BigInt& b) { return ct_divide(a * b, gcd(a, b)); } /* Sets result to a^-1 * 2^k mod a @@ -19025,1770 +17372,1511 @@ A const time implementation of this algorithm is described in "Constant Time Modular Inversion" Joppe W. Bos http://www.joppebos.com/files/CTInversion.pdf */ -size_t almost_montgomery_inverse(BigInt& result, - const BigInt& a, - const BigInt& p) - { - size_t k = 0; - - BigInt u = p, v = a, r = 0, s = 1; - - while(v > 0) - { - if(u.is_even()) - { - u >>= 1; - s <<= 1; - } - else if(v.is_even()) - { - v >>= 1; - r <<= 1; - } - else if(u > v) - { - u -= v; - u >>= 1; - r += s; - s <<= 1; - } - else - { - v -= u; - v >>= 1; - s += r; - r <<= 1; - } - - ++k; - } - - if(r >= p) - { - r -= p; - } - - result = p - r; - - return k; - } - -BigInt normalized_montgomery_inverse(const BigInt& a, const BigInt& p) - { - BigInt r; - size_t k = almost_montgomery_inverse(r, a, p); - - for(size_t i = 0; i != k; ++i) - { - if(r.is_odd()) - r += p; - r >>= 1; - } - - return r; - } - -BigInt ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod) - { - if(n.is_negative() || mod.is_negative()) - throw Invalid_Argument("ct_inverse_mod_odd_modulus: arguments must be non-negative"); - if(mod < 3 || mod.is_even()) - throw Invalid_Argument("Bad modulus to ct_inverse_mod_odd_modulus"); - if(n >= mod) - throw Invalid_Argument("ct_inverse_mod_odd_modulus n >= mod not supported"); - - /* - This uses a modular inversion algorithm designed by Niels Möller - and implemented in Nettle. The same algorithm was later also - adapted to GMP in mpn_sec_invert. - - It can be easily implemented in a way that does not depend on - secret branches or memory lookups, providing resistance against - some forms of side channel attack. - - There is also a description of the algorithm in Appendix 5 of "Fast - Software Polynomial Multiplication on ARM Processors using the NEON Engine" - by Danilo Câmara, Conrado P. L. Gouvêa, Julio López, and Ricardo - Dahab in LNCS 8182 - https://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf - - Thanks to Niels for creating the algorithm, explaining some things - about it, and the reference to the paper. - */ - - // todo allow this to be pre-calculated and passed in as arg - BigInt mp1o2 = (mod + 1) >> 1; - - const size_t mod_words = mod.sig_words(); - BOTAN_ASSERT(mod_words > 0, "Not empty"); - - BigInt a = n; - BigInt b = mod; - BigInt u = 1, v = 0; - - a.grow_to(mod_words); - u.grow_to(mod_words); - v.grow_to(mod_words); - mp1o2.grow_to(mod_words); - - secure_vector& a_w = a.get_word_vector(); - secure_vector& b_w = b.get_word_vector(); - secure_vector& u_w = u.get_word_vector(); - secure_vector& v_w = v.get_word_vector(); - - CT::poison(a_w.data(), a_w.size()); - CT::poison(b_w.data(), b_w.size()); - CT::poison(u_w.data(), u_w.size()); - CT::poison(v_w.data(), v_w.size()); - - // Only n.bits() + mod.bits() iterations are required, but avoid leaking the size of n - size_t bits = 2 * mod.bits(); - - while(bits--) - { - /* - const word odd = a.is_odd(); - a -= odd * b; - const word underflow = a.is_negative(); - b += a * underflow; - a.set_sign(BigInt::Positive); - - a >>= 1; - - if(underflow) - { - std::swap(u, v); - } - - u -= odd * v; - u += u.is_negative() * mod; - - const word odd_u = u.is_odd(); - - u >>= 1; - u += mp1o2 * odd_u; - */ - - const word odd_a = a_w[0] & 1; - - //if(odd_a) a -= b - word underflow = bigint_cnd_sub(odd_a, a_w.data(), b_w.data(), mod_words); - - //if(underflow) { b -= a; a = abs(a); swap(u, v); } - bigint_cnd_add(underflow, b_w.data(), a_w.data(), mod_words); - bigint_cnd_abs(underflow, a_w.data(), mod_words); - bigint_cnd_swap(underflow, u_w.data(), v_w.data(), mod_words); - - // a >>= 1 - bigint_shr1(a_w.data(), mod_words, 0, 1); - - //if(odd_a) u -= v; - word borrow = bigint_cnd_sub(odd_a, u_w.data(), v_w.data(), mod_words); - - // if(borrow) u += p - bigint_cnd_add(borrow, u_w.data(), mod.data(), mod_words); - - const word odd_u = u_w[0] & 1; - - // u >>= 1 - bigint_shr1(u_w.data(), mod_words, 0, 1); - - //if(odd_u) u += mp1o2; - bigint_cnd_add(odd_u, u_w.data(), mp1o2.data(), mod_words); - } - - CT::unpoison(a_w.data(), a_w.size()); - CT::unpoison(b_w.data(), b_w.size()); - CT::unpoison(u_w.data(), u_w.size()); - CT::unpoison(v_w.data(), v_w.size()); - - BOTAN_ASSERT(a.is_zero(), "A is zero"); - - if(b != 1) - return 0; - - return v; - } - -/* -* Find the Modular Inverse -*/ -BigInt inverse_mod(const BigInt& n, const BigInt& mod) - { - if(mod.is_zero()) - throw BigInt::DivideByZero(); - if(mod.is_negative() || n.is_negative()) - throw Invalid_Argument("inverse_mod: arguments must be non-negative"); - if(n.is_zero()) - return 0; - - if(mod.is_odd() && n < mod) - return ct_inverse_mod_odd_modulus(n, mod); - - return inverse_euclid(n, mod); - } - -BigInt inverse_euclid(const BigInt& n, const BigInt& mod) - { - if(mod.is_zero()) - throw BigInt::DivideByZero(); - if(mod.is_negative() || n.is_negative()) - throw Invalid_Argument("inverse_mod: arguments must be non-negative"); - - if(n.is_zero() || (n.is_even() && mod.is_even())) - return 0; // fast fail checks - - BigInt u = mod, v = n; - BigInt A = 1, B = 0, C = 0, D = 1; - BigInt T0, T1, T2; - - while(u.is_nonzero()) - { - const size_t u_zero_bits = low_zero_bits(u); - u >>= u_zero_bits; - - const size_t v_zero_bits = low_zero_bits(v); - v >>= v_zero_bits; - - const bool u_gte_v = (u >= v); - - for(size_t i = 0; i != u_zero_bits; ++i) - { - const bool needs_adjust = A.is_odd() || B.is_odd(); - - T0 = A + n; - T1 = B - mod; - - A.ct_cond_assign(needs_adjust, T0); - B.ct_cond_assign(needs_adjust, T1); - - A >>= 1; - B >>= 1; - } - - for(size_t i = 0; i != v_zero_bits; ++i) - { - const bool needs_adjust = C.is_odd() || D.is_odd(); - T0 = C + n; - T1 = D - mod; - - C.ct_cond_assign(needs_adjust, T0); - D.ct_cond_assign(needs_adjust, T1); - - C >>= 1; - D >>= 1; - } - - T0 = u - v; - T1 = A - C; - T2 = B - D; - - T0.cond_flip_sign(!u_gte_v); - T1.cond_flip_sign(!u_gte_v); - T2.cond_flip_sign(!u_gte_v); - - u.ct_cond_assign(u_gte_v, T0); - A.ct_cond_assign(u_gte_v, T1); - B.ct_cond_assign(u_gte_v, T2); - - v.ct_cond_assign(!u_gte_v, T0); - C.ct_cond_assign(!u_gte_v, T1); - D.ct_cond_assign(!u_gte_v, T2); - } - - if(v != 1) - return 0; // no modular inverse - - while(D.is_negative()) - D += mod; - while(D >= mod) - D -= mod; - - return D; - } - -word monty_inverse(word a) - { - if(a % 2 == 0) - throw Invalid_Argument("monty_inverse only valid for odd integers"); - - /* - * From "A New Algorithm for Inversion mod p^k" by Çetin Kaya Koç - * https://eprint.iacr.org/2017/411.pdf sections 5 and 7. - */ - - word b = 1; - word r = 0; - - for(size_t i = 0; i != BOTAN_MP_WORD_BITS; ++i) - { - const word bi = b % 2; - r >>= 1; - r += bi << (BOTAN_MP_WORD_BITS - 1); - - b -= a * bi; - b >>= 1; - } - - // Now invert in addition space - r = (MP_WORD_MAX - r) + 1; - - return r; - } - -/* -* Modular Exponentiation -*/ -BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) - { - if(mod.is_negative() || mod == 1) - { - return 0; - } - - if(base.is_zero() || mod.is_zero()) - { - if(exp.is_zero()) - return 1; - return 0; - } - - Modular_Reducer reduce_mod(mod); - - const size_t exp_bits = exp.bits(); - - if(mod.is_odd()) - { - const size_t powm_window = 4; - - auto monty_mod = std::make_shared(mod, reduce_mod); - auto powm_base_mod = monty_precompute(monty_mod, reduce_mod.reduce(base), powm_window); - return monty_execute(*powm_base_mod, exp, exp_bits); - } - - /* - Support for even modulus is just a convenience and not considered - cryptographically important, so this implementation is slow ... - */ - BigInt accum = 1; - BigInt g = reduce_mod.reduce(base); - BigInt t; - - for(size_t i = 0; i != exp_bits; ++i) - { - t = reduce_mod.multiply(g, accum); - g = reduce_mod.square(g); - accum.ct_cond_assign(exp.get_bit(i), t); - } - return accum; - } - - -BigInt is_perfect_square(const BigInt& C) - { - if(C < 1) - throw Invalid_Argument("is_perfect_square requires C >= 1"); - if(C == 1) - return 1; - - const size_t n = C.bits(); - const size_t m = (n + 1) / 2; - const BigInt B = C + BigInt::power_of_2(m); - - BigInt X = BigInt::power_of_2(m) - 1; - BigInt X2 = (X*X); - - for(;;) - { - X = (X2 + C) / (2*X); - X2 = (X*X); - - if(X2 < B) - break; - } - - if(X2 == C) - return X; - else - return 0; - } - -/* -* Test for primality using Miller-Rabin -*/ -bool is_prime(const BigInt& n, - RandomNumberGenerator& rng, - size_t prob, - bool is_random) - { - if(n == 2) - return true; - if(n <= 1 || n.is_even()) - return false; - - const size_t n_bits = n.bits(); - - // Fast path testing for small numbers (<= 65521) - if(n_bits <= 16) - { - const uint16_t num = static_cast(n.word_at(0)); - - return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num); - } - - Modular_Reducer mod_n(n); - - if(rng.is_seeded()) - { - const size_t t = miller_rabin_test_iterations(n_bits, prob, is_random); - - if(is_miller_rabin_probable_prime(n, mod_n, rng, t) == false) - return false; - - return is_lucas_probable_prime(n, mod_n); - } - else - { - return is_bailie_psw_probable_prime(n, mod_n); - } - } - +size_t almost_montgomery_inverse(BigInt& result, const BigInt& a, const BigInt& p) { + size_t k = 0; + + BigInt u = p, v = a, r = 0, s = 1; + + while (v > 0) { + if (u.is_even()) { + u >>= 1; + s <<= 1; + } else if (v.is_even()) { + v >>= 1; + r <<= 1; + } else if (u > v) { + u -= v; + u >>= 1; + r += s; + s <<= 1; + } else { + v -= u; + v >>= 1; + s += r; + r <<= 1; + } + + ++k; + } + + if (r >= p) { + r -= p; + } + + result = p - r; + + return k; } -/* -* Modular Exponentiation Proxy -* (C) 1999-2007,2012,2018,2019 Jack Lloyd -* 2016 Matthias Gierlings -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +BigInt normalized_montgomery_inverse(const BigInt& a, const BigInt& p) { + BigInt r; + size_t k = almost_montgomery_inverse(r, a, p); + + for (size_t i = 0; i != k; ++i) { + if (r.is_odd()) r += p; + r >>= 1; + } + + return r; +} + +BigInt ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod) { + if (n.is_negative() || mod.is_negative()) + throw Invalid_Argument("ct_inverse_mod_odd_modulus: arguments must be non-negative"); + if (mod < 3 || mod.is_even()) + throw Invalid_Argument("Bad modulus to ct_inverse_mod_odd_modulus"); + if (n >= mod) throw Invalid_Argument("ct_inverse_mod_odd_modulus n >= mod not supported"); + + /* + This uses a modular inversion algorithm designed by Niels Möller + and implemented in Nettle. The same algorithm was later also + adapted to GMP in mpn_sec_invert. + + It can be easily implemented in a way that does not depend on + secret branches or memory lookups, providing resistance against + some forms of side channel attack. + + There is also a description of the algorithm in Appendix 5 of "Fast + Software Polynomial Multiplication on ARM Processors using the NEON Engine" + by Danilo Câmara, Conrado P. L. Gouvêa, Julio López, and Ricardo + Dahab in LNCS 8182 + https://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf + + Thanks to Niels for creating the algorithm, explaining some things + about it, and the reference to the paper. + */ + + // todo allow this to be pre-calculated and passed in as arg + BigInt mp1o2 = (mod + 1) >> 1; + + const size_t mod_words = mod.sig_words(); + BOTAN_ASSERT(mod_words > 0, "Not empty"); + + BigInt a = n; + BigInt b = mod; + BigInt u = 1, v = 0; + + a.grow_to(mod_words); + u.grow_to(mod_words); + v.grow_to(mod_words); + mp1o2.grow_to(mod_words); + + secure_vector& a_w = a.get_word_vector(); + secure_vector& b_w = b.get_word_vector(); + secure_vector& u_w = u.get_word_vector(); + secure_vector& v_w = v.get_word_vector(); + + CT::poison(a_w.data(), a_w.size()); + CT::poison(b_w.data(), b_w.size()); + CT::poison(u_w.data(), u_w.size()); + CT::poison(v_w.data(), v_w.size()); + + // Only n.bits() + mod.bits() iterations are required, but avoid leaking the size of n + size_t bits = 2 * mod.bits(); + + while (bits--) { + /* + const word odd = a.is_odd(); + a -= odd * b; + const word underflow = a.is_negative(); + b += a * underflow; + a.set_sign(BigInt::Positive); + + a >>= 1; + + if(underflow) + { + std::swap(u, v); + } + + u -= odd * v; + u += u.is_negative() * mod; + + const word odd_u = u.is_odd(); + + u >>= 1; + u += mp1o2 * odd_u; + */ + + const word odd_a = a_w[0] & 1; + + // if(odd_a) a -= b + word underflow = bigint_cnd_sub(odd_a, a_w.data(), b_w.data(), mod_words); + + // if(underflow) { b -= a; a = abs(a); swap(u, v); } + bigint_cnd_add(underflow, b_w.data(), a_w.data(), mod_words); + bigint_cnd_abs(underflow, a_w.data(), mod_words); + bigint_cnd_swap(underflow, u_w.data(), v_w.data(), mod_words); + + // a >>= 1 + bigint_shr1(a_w.data(), mod_words, 0, 1); + + // if(odd_a) u -= v; + word borrow = bigint_cnd_sub(odd_a, u_w.data(), v_w.data(), mod_words); + + // if(borrow) u += p + bigint_cnd_add(borrow, u_w.data(), mod.data(), mod_words); + + const word odd_u = u_w[0] & 1; + + // u >>= 1 + bigint_shr1(u_w.data(), mod_words, 0, 1); + + // if(odd_u) u += mp1o2; + bigint_cnd_add(odd_u, u_w.data(), mp1o2.data(), mod_words); + } + + CT::unpoison(a_w.data(), a_w.size()); + CT::unpoison(b_w.data(), b_w.size()); + CT::unpoison(u_w.data(), u_w.size()); + CT::unpoison(v_w.data(), v_w.size()); + + BOTAN_ASSERT(a.is_zero(), "A is zero"); + + if (b != 1) return 0; + + return v; +} + +/* + * Find the Modular Inverse + */ +BigInt inverse_mod(const BigInt& n, const BigInt& mod) { + if (mod.is_zero()) throw BigInt::DivideByZero(); + if (mod.is_negative() || n.is_negative()) + throw Invalid_Argument("inverse_mod: arguments must be non-negative"); + if (n.is_zero()) return 0; + + if (mod.is_odd() && n < mod) return ct_inverse_mod_odd_modulus(n, mod); + + return inverse_euclid(n, mod); +} + +BigInt inverse_euclid(const BigInt& n, const BigInt& mod) { + if (mod.is_zero()) throw BigInt::DivideByZero(); + if (mod.is_negative() || n.is_negative()) + throw Invalid_Argument("inverse_mod: arguments must be non-negative"); + + if (n.is_zero() || (n.is_even() && mod.is_even())) return 0; // fast fail checks + + BigInt u = mod, v = n; + BigInt A = 1, B = 0, C = 0, D = 1; + BigInt T0, T1, T2; + + while (u.is_nonzero()) { + const size_t u_zero_bits = low_zero_bits(u); + u >>= u_zero_bits; + + const size_t v_zero_bits = low_zero_bits(v); + v >>= v_zero_bits; + + const bool u_gte_v = (u >= v); + + for (size_t i = 0; i != u_zero_bits; ++i) { + const bool needs_adjust = A.is_odd() || B.is_odd(); + + T0 = A + n; + T1 = B - mod; + + A.ct_cond_assign(needs_adjust, T0); + B.ct_cond_assign(needs_adjust, T1); + + A >>= 1; + B >>= 1; + } + + for (size_t i = 0; i != v_zero_bits; ++i) { + const bool needs_adjust = C.is_odd() || D.is_odd(); + T0 = C + n; + T1 = D - mod; + + C.ct_cond_assign(needs_adjust, T0); + D.ct_cond_assign(needs_adjust, T1); + + C >>= 1; + D >>= 1; + } + + T0 = u - v; + T1 = A - C; + T2 = B - D; + + T0.cond_flip_sign(!u_gte_v); + T1.cond_flip_sign(!u_gte_v); + T2.cond_flip_sign(!u_gte_v); + + u.ct_cond_assign(u_gte_v, T0); + A.ct_cond_assign(u_gte_v, T1); + B.ct_cond_assign(u_gte_v, T2); + + v.ct_cond_assign(!u_gte_v, T0); + C.ct_cond_assign(!u_gte_v, T1); + D.ct_cond_assign(!u_gte_v, T2); + } + + if (v != 1) return 0; // no modular inverse + + while (D.is_negative()) D += mod; + while (D >= mod) D -= mod; + + return D; +} + +word monty_inverse(word a) { + if (a % 2 == 0) throw Invalid_Argument("monty_inverse only valid for odd integers"); + + /* + * From "A New Algorithm for Inversion mod p^k" by Çetin Kaya Koç + * https://eprint.iacr.org/2017/411.pdf sections 5 and 7. + */ + + word b = 1; + word r = 0; + + for (size_t i = 0; i != BOTAN_MP_WORD_BITS; ++i) { + const word bi = b % 2; + r >>= 1; + r += bi << (BOTAN_MP_WORD_BITS - 1); + + b -= a * bi; + b >>= 1; + } + + // Now invert in addition space + r = (MP_WORD_MAX - r) + 1; + + return r; +} + +/* + * Modular Exponentiation + */ +BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) { + if (mod.is_negative() || mod == 1) { + return 0; + } + + if (base.is_zero() || mod.is_zero()) { + if (exp.is_zero()) return 1; + return 0; + } + + Modular_Reducer reduce_mod(mod); + + const size_t exp_bits = exp.bits(); + + if (mod.is_odd()) { + const size_t powm_window = 4; + + auto monty_mod = std::make_shared(mod, reduce_mod); + auto powm_base_mod = monty_precompute(monty_mod, reduce_mod.reduce(base), powm_window); + return monty_execute(*powm_base_mod, exp, exp_bits); + } + + /* + Support for even modulus is just a convenience and not considered + cryptographically important, so this implementation is slow ... + */ + BigInt accum = 1; + BigInt g = reduce_mod.reduce(base); + BigInt t; + + for (size_t i = 0; i != exp_bits; ++i) { + t = reduce_mod.multiply(g, accum); + g = reduce_mod.square(g); + accum.ct_cond_assign(exp.get_bit(i), t); + } + return accum; +} + +BigInt is_perfect_square(const BigInt& C) { + if (C < 1) throw Invalid_Argument("is_perfect_square requires C >= 1"); + if (C == 1) return 1; + + const size_t n = C.bits(); + const size_t m = (n + 1) / 2; + const BigInt B = C + BigInt::power_of_2(m); + + BigInt X = BigInt::power_of_2(m) - 1; + BigInt X2 = (X * X); + + for (;;) { + X = (X2 + C) / (2 * X); + X2 = (X * X); + + if (X2 < B) break; + } + + if (X2 == C) + return X; + else + return 0; +} + +/* + * Test for primality using Miller-Rabin + */ +bool is_prime(const BigInt& n, RandomNumberGenerator& rng, size_t prob, bool is_random) { + if (n == 2) return true; + if (n <= 1 || n.is_even()) return false; + + const size_t n_bits = n.bits(); + + // Fast path testing for small numbers (<= 65521) + if (n_bits <= 16) { + const uint16_t num = static_cast(n.word_at(0)); + + return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num); + } + + Modular_Reducer mod_n(n); + + if (rng.is_seeded()) { + const size_t t = miller_rabin_test_iterations(n_bits, prob, is_random); + + if (is_miller_rabin_probable_prime(n, mod_n, rng, t) == false) return false; + + return is_lucas_probable_prime(n, mod_n); + } else { + return is_bailie_psw_probable_prime(n, mod_n); + } +} + +} // namespace Botan +/* + * Modular Exponentiation Proxy + * (C) 1999-2007,2012,2018,2019 Jack Lloyd + * 2016 Matthias Gierlings + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -class Modular_Exponentiator - { +class Modular_Exponentiator { public: - virtual void set_base(const BigInt&) = 0; - virtual void set_exponent(const BigInt&) = 0; - virtual BigInt execute() const = 0; - virtual Modular_Exponentiator* copy() const = 0; + virtual void set_base(const BigInt&) = 0; + virtual void set_exponent(const BigInt&) = 0; + virtual BigInt execute() const = 0; + virtual Modular_Exponentiator* copy() const = 0; - Modular_Exponentiator() = default; - Modular_Exponentiator(const Modular_Exponentiator&) = default; - Modular_Exponentiator & operator=(const Modular_Exponentiator&) = default; - virtual ~Modular_Exponentiator() = default; - }; + Modular_Exponentiator() = default; + Modular_Exponentiator(const Modular_Exponentiator&) = default; + Modular_Exponentiator& operator=(const Modular_Exponentiator&) = default; + virtual ~Modular_Exponentiator() = default; +}; namespace { /** -* Fixed Window Exponentiator -*/ -class Fixed_Window_Exponentiator final : public Modular_Exponentiator - { + * Fixed Window Exponentiator + */ +class Fixed_Window_Exponentiator final : public Modular_Exponentiator { public: - void set_exponent(const BigInt& e) override { m_exp = e; } - void set_base(const BigInt&) override; - BigInt execute() const override; + void set_exponent(const BigInt& e) override { m_exp = e; } + void set_base(const BigInt&) override; + BigInt execute() const override; - Modular_Exponentiator* copy() const override - { return new Fixed_Window_Exponentiator(*this); } + Modular_Exponentiator* copy() const override { return new Fixed_Window_Exponentiator(*this); } + + Fixed_Window_Exponentiator(const BigInt&, Power_Mod::Usage_Hints); - Fixed_Window_Exponentiator(const BigInt&, Power_Mod::Usage_Hints); private: - Modular_Reducer m_reducer; - BigInt m_exp; - size_t m_window_bits; - std::vector m_g; - Power_Mod::Usage_Hints m_hints; - }; + Modular_Reducer m_reducer; + BigInt m_exp; + size_t m_window_bits; + std::vector m_g; + Power_Mod::Usage_Hints m_hints; +}; -void Fixed_Window_Exponentiator::set_base(const BigInt& base) - { - m_window_bits = Power_Mod::window_bits(m_exp.bits(), base.bits(), m_hints); +void Fixed_Window_Exponentiator::set_base(const BigInt& base) { + m_window_bits = Power_Mod::window_bits(m_exp.bits(), base.bits(), m_hints); - m_g.resize(static_cast(1) << m_window_bits); - m_g[0] = 1; - m_g[1] = m_reducer.reduce(base); + m_g.resize(static_cast(1) << m_window_bits); + m_g[0] = 1; + m_g[1] = m_reducer.reduce(base); - for(size_t i = 2; i != m_g.size(); ++i) - m_g[i] = m_reducer.multiply(m_g[i-1], m_g[1]); - } + for (size_t i = 2; i != m_g.size(); ++i) m_g[i] = m_reducer.multiply(m_g[i - 1], m_g[1]); +} -BigInt Fixed_Window_Exponentiator::execute() const - { - const size_t exp_nibbles = (m_exp.bits() + m_window_bits - 1) / m_window_bits; +BigInt Fixed_Window_Exponentiator::execute() const { + const size_t exp_nibbles = (m_exp.bits() + m_window_bits - 1) / m_window_bits; - BigInt x = 1; + BigInt x = 1; - for(size_t i = exp_nibbles; i > 0; --i) - { - for(size_t j = 0; j != m_window_bits; ++j) - x = m_reducer.square(x); + for (size_t i = exp_nibbles; i > 0; --i) { + for (size_t j = 0; j != m_window_bits; ++j) x = m_reducer.square(x); - const uint32_t nibble = m_exp.get_substring(m_window_bits*(i-1), m_window_bits); - - // not const time: - x = m_reducer.multiply(x, m_g[nibble]); - } - return x; - } - -/* -* Fixed_Window_Exponentiator Constructor -*/ -Fixed_Window_Exponentiator::Fixed_Window_Exponentiator(const BigInt& n, - Power_Mod::Usage_Hints hints) - : m_reducer{Modular_Reducer(n)}, m_exp{}, m_window_bits{}, m_g{}, m_hints{hints} - {} - -class Montgomery_Exponentiator final : public Modular_Exponentiator - { - public: - void set_exponent(const BigInt& e) override { m_e = e; } - void set_base(const BigInt&) override; - BigInt execute() const override; - - Modular_Exponentiator* copy() const override - { return new Montgomery_Exponentiator(*this); } - - Montgomery_Exponentiator(const BigInt&, Power_Mod::Usage_Hints); - private: - BigInt m_p; - Modular_Reducer m_mod_p; - std::shared_ptr m_monty_params; - std::shared_ptr m_monty; - - BigInt m_e; - Power_Mod::Usage_Hints m_hints; - }; - -void Montgomery_Exponentiator::set_base(const BigInt& base) - { - size_t window_bits = Power_Mod::window_bits(m_e.bits(), base.bits(), m_hints); - m_monty = monty_precompute(m_monty_params, m_mod_p.reduce(base), window_bits); - } - -BigInt Montgomery_Exponentiator::execute() const - { - /* - This leaks size of e via loop iterations, not possible to fix without - breaking this API. Round up to avoid leaking fine details. - */ - return monty_execute(*m_monty, m_e, round_up(m_e.bits(), 8)); - } - -Montgomery_Exponentiator::Montgomery_Exponentiator(const BigInt& mod, - Power_Mod::Usage_Hints hints) : - m_p(mod), - m_mod_p(mod), - m_monty_params(std::make_shared(m_p, m_mod_p)), - m_hints(hints) - { - } + const uint32_t nibble = m_exp.get_substring(m_window_bits * (i - 1), m_window_bits); + // not const time: + x = m_reducer.multiply(x, m_g[nibble]); + } + return x; } /* -* Power_Mod Constructor -*/ -Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints, bool disable_monty) - { - set_modulus(n, hints, disable_monty); - } + * Fixed_Window_Exponentiator Constructor + */ +Fixed_Window_Exponentiator::Fixed_Window_Exponentiator(const BigInt& n, + Power_Mod::Usage_Hints hints) + : m_reducer{Modular_Reducer(n)}, m_exp{}, m_window_bits{}, m_g{}, m_hints{hints} {} + +class Montgomery_Exponentiator final : public Modular_Exponentiator { + public: + void set_exponent(const BigInt& e) override { m_e = e; } + void set_base(const BigInt&) override; + BigInt execute() const override; + + Modular_Exponentiator* copy() const override { return new Montgomery_Exponentiator(*this); } + + Montgomery_Exponentiator(const BigInt&, Power_Mod::Usage_Hints); + + private: + BigInt m_p; + Modular_Reducer m_mod_p; + std::shared_ptr m_monty_params; + std::shared_ptr m_monty; + + BigInt m_e; + Power_Mod::Usage_Hints m_hints; +}; + +void Montgomery_Exponentiator::set_base(const BigInt& base) { + size_t window_bits = Power_Mod::window_bits(m_e.bits(), base.bits(), m_hints); + m_monty = monty_precompute(m_monty_params, m_mod_p.reduce(base), window_bits); +} + +BigInt Montgomery_Exponentiator::execute() const { + /* + This leaks size of e via loop iterations, not possible to fix without + breaking this API. Round up to avoid leaking fine details. + */ + return monty_execute(*m_monty, m_e, round_up(m_e.bits(), 8)); +} + +Montgomery_Exponentiator::Montgomery_Exponentiator(const BigInt& mod, Power_Mod::Usage_Hints hints) + : m_p(mod), + m_mod_p(mod), + m_monty_params(std::make_shared(m_p, m_mod_p)), + m_hints(hints) {} + +} // namespace + +/* + * Power_Mod Constructor + */ +Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints, bool disable_monty) { + set_modulus(n, hints, disable_monty); +} Power_Mod::~Power_Mod() { /* for ~unique_ptr */ } /* -* Power_Mod Copy Constructor -*/ -Power_Mod::Power_Mod(const Power_Mod& other) - { - if(other.m_core.get()) - m_core.reset(other.m_core->copy()); - } + * Power_Mod Copy Constructor + */ +Power_Mod::Power_Mod(const Power_Mod& other) { + if (other.m_core.get()) m_core.reset(other.m_core->copy()); +} /* -* Power_Mod Assignment Operator -*/ -Power_Mod& Power_Mod::operator=(const Power_Mod& other) - { - if(this != &other) - { - if(other.m_core) - m_core.reset(other.m_core->copy()); - else - m_core.reset(); - } - return (*this); - } + * Power_Mod Assignment Operator + */ +Power_Mod& Power_Mod::operator=(const Power_Mod& other) { + if (this != &other) { + if (other.m_core) + m_core.reset(other.m_core->copy()); + else + m_core.reset(); + } + return (*this); +} /* -* Set the modulus -*/ -void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints, bool disable_monty) const - { - // Allow set_modulus(0) to mean "drop old state" + * Set the modulus + */ +void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints, bool disable_monty) const { + // Allow set_modulus(0) to mean "drop old state" - m_core.reset(); + m_core.reset(); - if(n != 0) - { - if(n.is_odd() && disable_monty == false) - m_core.reset(new Montgomery_Exponentiator(n, hints)); - else - m_core.reset(new Fixed_Window_Exponentiator(n, hints)); - } - } + if (n != 0) { + if (n.is_odd() && disable_monty == false) + m_core.reset(new Montgomery_Exponentiator(n, hints)); + else + m_core.reset(new Fixed_Window_Exponentiator(n, hints)); + } +} /* -* Set the base -*/ -void Power_Mod::set_base(const BigInt& b) const - { - if(b.is_negative()) - throw Invalid_Argument("Power_Mod::set_base: arg must be non-negative"); + * Set the base + */ +void Power_Mod::set_base(const BigInt& b) const { + if (b.is_negative()) throw Invalid_Argument("Power_Mod::set_base: arg must be non-negative"); - if(!m_core) - throw Internal_Error("Power_Mod::set_base: m_core was NULL"); - m_core->set_base(b); - } + if (!m_core) throw Internal_Error("Power_Mod::set_base: m_core was NULL"); + m_core->set_base(b); +} /* -* Set the exponent -*/ -void Power_Mod::set_exponent(const BigInt& e) const - { - if(e.is_negative()) - throw Invalid_Argument("Power_Mod::set_exponent: arg must be > 0"); + * Set the exponent + */ +void Power_Mod::set_exponent(const BigInt& e) const { + if (e.is_negative()) throw Invalid_Argument("Power_Mod::set_exponent: arg must be > 0"); - if(!m_core) - throw Internal_Error("Power_Mod::set_exponent: m_core was NULL"); - m_core->set_exponent(e); - } + if (!m_core) throw Internal_Error("Power_Mod::set_exponent: m_core was NULL"); + m_core->set_exponent(e); +} /* -* Compute the result -*/ -BigInt Power_Mod::execute() const - { - if(!m_core) - throw Internal_Error("Power_Mod::execute: m_core was NULL"); - return m_core->execute(); - } + * Compute the result + */ +BigInt Power_Mod::execute() const { + if (!m_core) throw Internal_Error("Power_Mod::execute: m_core was NULL"); + return m_core->execute(); +} /* -* Try to choose a good window size -*/ -size_t Power_Mod::window_bits(size_t exp_bits, size_t, - Power_Mod::Usage_Hints hints) - { - static const size_t wsize[][2] = { - { 1434, 7 }, - { 539, 6 }, - { 197, 4 }, - { 70, 3 }, - { 17, 2 }, - { 0, 0 } - }; + * Try to choose a good window size + */ +size_t Power_Mod::window_bits(size_t exp_bits, size_t, Power_Mod::Usage_Hints hints) { + static const size_t wsize[][2] = {{1434, 7}, {539, 6}, {197, 4}, {70, 3}, {17, 2}, {0, 0}}; - size_t window_bits = 1; + size_t window_bits = 1; - if(exp_bits) - { - for(size_t j = 0; wsize[j][0]; ++j) - { - if(exp_bits >= wsize[j][0]) - { - window_bits += wsize[j][1]; - break; + if (exp_bits) { + for (size_t j = 0; wsize[j][0]; ++j) { + if (exp_bits >= wsize[j][0]) { + window_bits += wsize[j][1]; + break; } - } - } + } + } - if(hints & Power_Mod::BASE_IS_FIXED) - window_bits += 2; - if(hints & Power_Mod::EXP_IS_LARGE) - ++window_bits; + if (hints & Power_Mod::BASE_IS_FIXED) window_bits += 2; + if (hints & Power_Mod::EXP_IS_LARGE) ++window_bits; - return window_bits; - } + return window_bits; +} namespace { /* -* Choose potentially useful hints -*/ -Power_Mod::Usage_Hints choose_base_hints(const BigInt& b, const BigInt& n) - { - if(b == 2) - return Power_Mod::Usage_Hints(Power_Mod::BASE_IS_2 | - Power_Mod::BASE_IS_SMALL); + * Choose potentially useful hints + */ +Power_Mod::Usage_Hints choose_base_hints(const BigInt& b, const BigInt& n) { + if (b == 2) return Power_Mod::Usage_Hints(Power_Mod::BASE_IS_2 | Power_Mod::BASE_IS_SMALL); - const size_t b_bits = b.bits(); - const size_t n_bits = n.bits(); + const size_t b_bits = b.bits(); + const size_t n_bits = n.bits(); - if(b_bits < n_bits / 32) - return Power_Mod::BASE_IS_SMALL; - if(b_bits > n_bits / 4) - return Power_Mod::BASE_IS_LARGE; - - return Power_Mod::NO_HINTS; - } - -/* -* Choose potentially useful hints -*/ -Power_Mod::Usage_Hints choose_exp_hints(const BigInt& e, const BigInt& n) - { - const size_t e_bits = e.bits(); - const size_t n_bits = n.bits(); - - if(e_bits < n_bits / 32) - return Power_Mod::BASE_IS_SMALL; - if(e_bits > n_bits / 4) - return Power_Mod::BASE_IS_LARGE; - return Power_Mod::NO_HINTS; - } + if (b_bits < n_bits / 32) return Power_Mod::BASE_IS_SMALL; + if (b_bits > n_bits / 4) return Power_Mod::BASE_IS_LARGE; + return Power_Mod::NO_HINTS; } /* -* Fixed_Exponent_Power_Mod Constructor -*/ -Fixed_Exponent_Power_Mod::Fixed_Exponent_Power_Mod(const BigInt& e, - const BigInt& n, - Usage_Hints hints) : - Power_Mod(n, Usage_Hints(hints | EXP_IS_FIXED | choose_exp_hints(e, n))) - { - set_exponent(e); - } - -/* -* Fixed_Base_Power_Mod Constructor -*/ -Fixed_Base_Power_Mod::Fixed_Base_Power_Mod(const BigInt& b, const BigInt& n, - Usage_Hints hints) : - Power_Mod(n, Usage_Hints(hints | BASE_IS_FIXED | choose_base_hints(b, n))) - { - set_base(b); - } + * Choose potentially useful hints + */ +Power_Mod::Usage_Hints choose_exp_hints(const BigInt& e, const BigInt& n) { + const size_t e_bits = e.bits(); + const size_t n_bits = n.bits(); + if (e_bits < n_bits / 32) return Power_Mod::BASE_IS_SMALL; + if (e_bits > n_bits / 4) return Power_Mod::BASE_IS_LARGE; + return Power_Mod::NO_HINTS; } -/* -* (C) 2016,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace + +/* + * Fixed_Exponent_Power_Mod Constructor + */ +Fixed_Exponent_Power_Mod::Fixed_Exponent_Power_Mod(const BigInt& e, const BigInt& n, + Usage_Hints hints) + : Power_Mod(n, Usage_Hints(hints | EXP_IS_FIXED | choose_exp_hints(e, n))) { + set_exponent(e); +} + +/* + * Fixed_Base_Power_Mod Constructor + */ +Fixed_Base_Power_Mod::Fixed_Base_Power_Mod(const BigInt& b, const BigInt& n, Usage_Hints hints) + : Power_Mod(n, Usage_Hints(hints | BASE_IS_FIXED | choose_base_hints(b, n))) { + set_base(b); +} + +} // namespace Botan +/* + * (C) 2016,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C) - { - if(C <= 1) - return false; - else if(C == 2) - return true; - else if(C.is_even()) - return false; - else if(C == 3 || C == 5 || C == 7 || C == 11 || C == 13) - return true; +bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C) { + if (C <= 1) + return false; + else if (C == 2) + return true; + else if (C.is_even()) + return false; + else if (C == 3 || C == 5 || C == 7 || C == 11 || C == 13) + return true; - BigInt D = 5; + BigInt D = 5; - for(;;) - { - int32_t j = jacobi(D, C); - if(j == 0) - return false; + for (;;) { + int32_t j = jacobi(D, C); + if (j == 0) return false; - if(j == -1) - break; + if (j == -1) break; - // Check 5, -7, 9, -11, 13, -15, 17, ... - if(D.is_negative()) - { - D.flip_sign(); - D += 2; - } - else - { - D += 2; - D.flip_sign(); - } + // Check 5, -7, 9, -11, 13, -15, 17, ... + if (D.is_negative()) { + D.flip_sign(); + D += 2; + } else { + D += 2; + D.flip_sign(); + } - if(D == 17 && is_perfect_square(C).is_nonzero()) - return false; - } + if (D == 17 && is_perfect_square(C).is_nonzero()) return false; + } - const BigInt K = C + 1; - const size_t K_bits = K.bits() - 1; + const BigInt K = C + 1; + const size_t K_bits = K.bits() - 1; - BigInt U = 1; - BigInt V = 1; + BigInt U = 1; + BigInt V = 1; - BigInt Ut, Vt, U2, V2; + BigInt Ut, Vt, U2, V2; - for(size_t i = 0; i != K_bits; ++i) - { - const uint8_t k_bit = K.get_bit(K_bits - 1 - i); + for (size_t i = 0; i != K_bits; ++i) { + const uint8_t k_bit = K.get_bit(K_bits - 1 - i); - Ut = mod_C.multiply(U, V); + Ut = mod_C.multiply(U, V); - Vt = mod_C.reduce(mod_C.square(V) + mod_C.multiply(D, mod_C.square(U))); - if(Vt.is_odd()) - Vt += C; - Vt >>= 1; - Vt = mod_C.reduce(Vt); + Vt = mod_C.reduce(mod_C.square(V) + mod_C.multiply(D, mod_C.square(U))); + if (Vt.is_odd()) Vt += C; + Vt >>= 1; + Vt = mod_C.reduce(Vt); - U = Ut; - V = Vt; + U = Ut; + V = Vt; - U2 = mod_C.reduce(Ut + Vt); - if(U2.is_odd()) - U2 += C; - U2 >>= 1; + U2 = mod_C.reduce(Ut + Vt); + if (U2.is_odd()) U2 += C; + U2 >>= 1; - V2 = mod_C.reduce(Vt + Ut*D); - if(V2.is_odd()) - V2 += C; - V2 >>= 1; + V2 = mod_C.reduce(Vt + Ut * D); + if (V2.is_odd()) V2 += C; + V2 >>= 1; - U.ct_cond_assign(k_bit, U2); - V.ct_cond_assign(k_bit, V2); - } - - return (U == 0); - } - -bool is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n) - { - auto monty_n = std::make_shared(n, mod_n); - return passes_miller_rabin_test(n, mod_n, monty_n, 2) && is_lucas_probable_prime(n, mod_n); - } - -bool is_bailie_psw_probable_prime(const BigInt& n) - { - Modular_Reducer mod_n(n); - return is_bailie_psw_probable_prime(n, mod_n); - } - -bool passes_miller_rabin_test(const BigInt& n, - const Modular_Reducer& mod_n, - const std::shared_ptr& monty_n, - const BigInt& a) - { - BOTAN_ASSERT_NOMSG(n > 1); - - const BigInt n_minus_1 = n - 1; - const size_t s = low_zero_bits(n_minus_1); - const BigInt nm1_s = n_minus_1 >> s; - const size_t n_bits = n.bits(); - - const size_t powm_window = 4; - - auto powm_a_n = monty_precompute(monty_n, a, powm_window); - - BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits); - - if(y == 1 || y == n_minus_1) - return true; - - for(size_t i = 1; i != s; ++i) - { - y = mod_n.square(y); - - if(y == 1) // found a non-trivial square root - return false; - - /* - -1 is the trivial square root of unity, so ``a`` is not a - witness for this number - give up - */ - if(y == n_minus_1) - return true; - } - - return false; - } - -bool is_miller_rabin_probable_prime(const BigInt& n, - const Modular_Reducer& mod_n, - RandomNumberGenerator& rng, - size_t test_iterations) - { - BOTAN_ASSERT_NOMSG(n > 1); - - auto monty_n = std::make_shared(n, mod_n); - - for(size_t i = 0; i != test_iterations; ++i) - { - const BigInt a = BigInt::random_integer(rng, 2, n); - - if(!passes_miller_rabin_test(n, mod_n, monty_n, a)) - return false; - } - - // Failed to find a counterexample - return true; - } - - -size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random) - { - const size_t base = (prob + 2) / 2; // worst case 4^-t error rate - - /* - * If the candidate prime was maliciously constructed, we can't rely - * on arguments based on p being random. - */ - if(random == false) - return base; - - /* - * For randomly chosen numbers we can use the estimates from - * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf - * - * These values are derived from the inequality for p(k,t) given on - * the second page. - */ - if(prob <= 128) - { - if(n_bits >= 1536) - return 4; // < 2^-133 - if(n_bits >= 1024) - return 6; // < 2^-133 - if(n_bits >= 512) - return 12; // < 2^-129 - if(n_bits >= 256) - return 29; // < 2^-128 - } - - /* - If the user desires a smaller error probability than we have - precomputed error estimates for, just fall back to using the worst - case error rate. - */ - return base; - } + U.ct_cond_assign(k_bit, U2); + V.ct_cond_assign(k_bit, V2); + } + return (U == 0); } -/* -* Small Primes Table -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +bool is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n) { + auto monty_n = std::make_shared(n, mod_n); + return passes_miller_rabin_test(n, mod_n, monty_n, 2) && is_lucas_probable_prime(n, mod_n); +} + +bool is_bailie_psw_probable_prime(const BigInt& n) { + Modular_Reducer mod_n(n); + return is_bailie_psw_probable_prime(n, mod_n); +} + +bool passes_miller_rabin_test(const BigInt& n, const Modular_Reducer& mod_n, + const std::shared_ptr& monty_n, const BigInt& a) { + BOTAN_ASSERT_NOMSG(n > 1); + + const BigInt n_minus_1 = n - 1; + const size_t s = low_zero_bits(n_minus_1); + const BigInt nm1_s = n_minus_1 >> s; + const size_t n_bits = n.bits(); + + const size_t powm_window = 4; + + auto powm_a_n = monty_precompute(monty_n, a, powm_window); + + BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits); + + if (y == 1 || y == n_minus_1) return true; + + for (size_t i = 1; i != s; ++i) { + y = mod_n.square(y); + + if (y == 1) // found a non-trivial square root + return false; + + /* + -1 is the trivial square root of unity, so ``a`` is not a + witness for this number - give up + */ + if (y == n_minus_1) return true; + } + + return false; +} + +bool is_miller_rabin_probable_prime(const BigInt& n, const Modular_Reducer& mod_n, + RandomNumberGenerator& rng, size_t test_iterations) { + BOTAN_ASSERT_NOMSG(n > 1); + + auto monty_n = std::make_shared(n, mod_n); + + for (size_t i = 0; i != test_iterations; ++i) { + const BigInt a = BigInt::random_integer(rng, 2, n); + + if (!passes_miller_rabin_test(n, mod_n, monty_n, a)) return false; + } + + // Failed to find a counterexample + return true; +} + +size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random) { + const size_t base = (prob + 2) / 2; // worst case 4^-t error rate + + /* + * If the candidate prime was maliciously constructed, we can't rely + * on arguments based on p being random. + */ + if (random == false) return base; + + /* + * For randomly chosen numbers we can use the estimates from + * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf + * + * These values are derived from the inequality for p(k,t) given on + * the second page. + */ + if (prob <= 128) { + if (n_bits >= 1536) return 4; // < 2^-133 + if (n_bits >= 1024) return 6; // < 2^-133 + if (n_bits >= 512) return 12; // < 2^-129 + if (n_bits >= 256) return 29; // < 2^-128 + } + + /* + If the user desires a smaller error probability than we have + precomputed error estimates for, just fall back to using the worst + case error rate. + */ + return base; +} + +} // namespace Botan +/* + * Small Primes Table + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -const uint16_t PRIMES[PRIME_TABLE_SIZE+1] = { - 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, - 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, - 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, - 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, - 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, - 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, - 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, - 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, - 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, - 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, - 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, - 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, - 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, - 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, - 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, - 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, - 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, - 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, - 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, - 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, - 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, - 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, - 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, - 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, - 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, - 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, - 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, - 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, - 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, - 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, - 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, - 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, - 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, - 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, - 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, - 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, - 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, - 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, - 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, - 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, - 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, - 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, - 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, - 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, - 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, - 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, - 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, - 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, - 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, - 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, - 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, - 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, - 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, - 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, - 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, - 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, - 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, - 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, - 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, - 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, - 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, - 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, - 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, - 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, - 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, - 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, - 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, - 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, - 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, - 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, - 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, - 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, - 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, - 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, - 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, - 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, - 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, - 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, - 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, - 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, - 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, - 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, - 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, - 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, - 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, - 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, - 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, - 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, - 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, - 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, - 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, - 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, - 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, - 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, - 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, - 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, - 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, - 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, - 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, - 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, - 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, - 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, - 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, - 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, - 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, - 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, - 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, - 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, - 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, - 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, - 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, - 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, 10039, -10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133, 10139, -10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223, 10243, -10247, 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313, 10321, -10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, -10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, -10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, -10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, -10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 10861, -10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, 10973, -10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071, 11083, -11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171, 11173, -11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279, 11287, -11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, -11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491, 11497, -11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621, -11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, -11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, -11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939, -11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037, 12041, -12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119, 12143, -12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, -12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343, 12347, -12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437, 12451, -12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 12539, -12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619, -12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, -12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, -12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, 12941, -12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, -13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 13127, 13147, -13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229, 13241, -13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, 13339, -13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457, 13463, -13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577, 13591, -13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691, -13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, -13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, -13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, 13997, -13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083, 14087, -14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, 14243, -14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347, 14369, -14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447, 14449, -14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551, 14557, -14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653, 14657, -14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, -14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, -14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947, -14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 15077, -15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161, 15173, -15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269, 15271, -15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349, 15359, -15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443, 15451, -15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, -15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661, -15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761, -15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, -15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, -15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, -16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187, 16189, -16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301, 16319, -16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, -16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529, 16547, -16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649, 16651, -16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 16759, -16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889, -16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, -16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, -17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, 17203, -17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, -17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401, 17417, -17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491, 17497, -17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 17609, -17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729, 17737, -17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839, 17851, -17863, 17881, 17891, 17903, 17909, 17911, 17921, 17923, 17929, 17939, 17957, -17959, 17971, 17977, 17981, 17987, 17989, 18013, 18041, 18043, 18047, 18049, -18059, 18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133, 18143, -18149, 18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233, 18251, -18253, 18257, 18269, 18287, 18289, 18301, 18307, 18311, 18313, 18329, 18341, -18353, 18367, 18371, 18379, 18397, 18401, 18413, 18427, 18433, 18439, 18443, -18451, 18457, 18461, 18481, 18493, 18503, 18517, 18521, 18523, 18539, 18541, -18553, 18583, 18587, 18593, 18617, 18637, 18661, 18671, 18679, 18691, 18701, -18713, 18719, 18731, 18743, 18749, 18757, 18773, 18787, 18793, 18797, 18803, -18839, 18859, 18869, 18899, 18911, 18913, 18917, 18919, 18947, 18959, 18973, -18979, 19001, 19009, 19013, 19031, 19037, 19051, 19069, 19073, 19079, 19081, -19087, 19121, 19139, 19141, 19157, 19163, 19181, 19183, 19207, 19211, 19213, -19219, 19231, 19237, 19249, 19259, 19267, 19273, 19289, 19301, 19309, 19319, -19333, 19373, 19379, 19381, 19387, 19391, 19403, 19417, 19421, 19423, 19427, -19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477, 19483, 19489, -19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571, 19577, 19583, 19597, -19603, 19609, 19661, 19681, 19687, 19697, 19699, 19709, 19717, 19727, 19739, -19751, 19753, 19759, 19763, 19777, 19793, 19801, 19813, 19819, 19841, 19843, -19853, 19861, 19867, 19889, 19891, 19913, 19919, 19927, 19937, 19949, 19961, -19963, 19973, 19979, 19991, 19993, 19997, 20011, 20021, 20023, 20029, 20047, -20051, 20063, 20071, 20089, 20101, 20107, 20113, 20117, 20123, 20129, 20143, -20147, 20149, 20161, 20173, 20177, 20183, 20201, 20219, 20231, 20233, 20249, -20261, 20269, 20287, 20297, 20323, 20327, 20333, 20341, 20347, 20353, 20357, -20359, 20369, 20389, 20393, 20399, 20407, 20411, 20431, 20441, 20443, 20477, -20479, 20483, 20507, 20509, 20521, 20533, 20543, 20549, 20551, 20563, 20593, -20599, 20611, 20627, 20639, 20641, 20663, 20681, 20693, 20707, 20717, 20719, -20731, 20743, 20747, 20749, 20753, 20759, 20771, 20773, 20789, 20807, 20809, -20849, 20857, 20873, 20879, 20887, 20897, 20899, 20903, 20921, 20929, 20939, -20947, 20959, 20963, 20981, 20983, 21001, 21011, 21013, 21017, 21019, 21023, -21031, 21059, 21061, 21067, 21089, 21101, 21107, 21121, 21139, 21143, 21149, -21157, 21163, 21169, 21179, 21187, 21191, 21193, 21211, 21221, 21227, 21247, -21269, 21277, 21283, 21313, 21317, 21319, 21323, 21341, 21347, 21377, 21379, -21383, 21391, 21397, 21401, 21407, 21419, 21433, 21467, 21481, 21487, 21491, -21493, 21499, 21503, 21517, 21521, 21523, 21529, 21557, 21559, 21563, 21569, -21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647, 21649, 21661, -21673, 21683, 21701, 21713, 21727, 21737, 21739, 21751, 21757, 21767, 21773, -21787, 21799, 21803, 21817, 21821, 21839, 21841, 21851, 21859, 21863, 21871, -21881, 21893, 21911, 21929, 21937, 21943, 21961, 21977, 21991, 21997, 22003, -22013, 22027, 22031, 22037, 22039, 22051, 22063, 22067, 22073, 22079, 22091, -22093, 22109, 22111, 22123, 22129, 22133, 22147, 22153, 22157, 22159, 22171, -22189, 22193, 22229, 22247, 22259, 22271, 22273, 22277, 22279, 22283, 22291, -22303, 22307, 22343, 22349, 22367, 22369, 22381, 22391, 22397, 22409, 22433, -22441, 22447, 22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543, -22549, 22567, 22571, 22573, 22613, 22619, 22621, 22637, 22639, 22643, 22651, -22669, 22679, 22691, 22697, 22699, 22709, 22717, 22721, 22727, 22739, 22741, -22751, 22769, 22777, 22783, 22787, 22807, 22811, 22817, 22853, 22859, 22861, -22871, 22877, 22901, 22907, 22921, 22937, 22943, 22961, 22963, 22973, 22993, -23003, 23011, 23017, 23021, 23027, 23029, 23039, 23041, 23053, 23057, 23059, -23063, 23071, 23081, 23087, 23099, 23117, 23131, 23143, 23159, 23167, 23173, -23189, 23197, 23201, 23203, 23209, 23227, 23251, 23269, 23279, 23291, 23293, -23297, 23311, 23321, 23327, 23333, 23339, 23357, 23369, 23371, 23399, 23417, -23431, 23447, 23459, 23473, 23497, 23509, 23531, 23537, 23539, 23549, 23557, -23561, 23563, 23567, 23581, 23593, 23599, 23603, 23609, 23623, 23627, 23629, -23633, 23663, 23669, 23671, 23677, 23687, 23689, 23719, 23741, 23743, 23747, -23753, 23761, 23767, 23773, 23789, 23801, 23813, 23819, 23827, 23831, 23833, -23857, 23869, 23873, 23879, 23887, 23893, 23899, 23909, 23911, 23917, 23929, -23957, 23971, 23977, 23981, 23993, 24001, 24007, 24019, 24023, 24029, 24043, -24049, 24061, 24071, 24077, 24083, 24091, 24097, 24103, 24107, 24109, 24113, -24121, 24133, 24137, 24151, 24169, 24179, 24181, 24197, 24203, 24223, 24229, -24239, 24247, 24251, 24281, 24317, 24329, 24337, 24359, 24371, 24373, 24379, -24391, 24407, 24413, 24419, 24421, 24439, 24443, 24469, 24473, 24481, 24499, -24509, 24517, 24527, 24533, 24547, 24551, 24571, 24593, 24611, 24623, 24631, -24659, 24671, 24677, 24683, 24691, 24697, 24709, 24733, 24749, 24763, 24767, -24781, 24793, 24799, 24809, 24821, 24841, 24847, 24851, 24859, 24877, 24889, -24907, 24917, 24919, 24923, 24943, 24953, 24967, 24971, 24977, 24979, 24989, -25013, 25031, 25033, 25037, 25057, 25073, 25087, 25097, 25111, 25117, 25121, -25127, 25147, 25153, 25163, 25169, 25171, 25183, 25189, 25219, 25229, 25237, -25243, 25247, 25253, 25261, 25301, 25303, 25307, 25309, 25321, 25339, 25343, -25349, 25357, 25367, 25373, 25391, 25409, 25411, 25423, 25439, 25447, 25453, -25457, 25463, 25469, 25471, 25523, 25537, 25541, 25561, 25577, 25579, 25583, -25589, 25601, 25603, 25609, 25621, 25633, 25639, 25643, 25657, 25667, 25673, -25679, 25693, 25703, 25717, 25733, 25741, 25747, 25759, 25763, 25771, 25793, -25799, 25801, 25819, 25841, 25847, 25849, 25867, 25873, 25889, 25903, 25913, -25919, 25931, 25933, 25939, 25943, 25951, 25969, 25981, 25997, 25999, 26003, -26017, 26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111, 26113, 26119, -26141, 26153, 26161, 26171, 26177, 26183, 26189, 26203, 26209, 26227, 26237, -26249, 26251, 26261, 26263, 26267, 26293, 26297, 26309, 26317, 26321, 26339, -26347, 26357, 26371, 26387, 26393, 26399, 26407, 26417, 26423, 26431, 26437, -26449, 26459, 26479, 26489, 26497, 26501, 26513, 26539, 26557, 26561, 26573, -26591, 26597, 26627, 26633, 26641, 26647, 26669, 26681, 26683, 26687, 26693, -26699, 26701, 26711, 26713, 26717, 26723, 26729, 26731, 26737, 26759, 26777, -26783, 26801, 26813, 26821, 26833, 26839, 26849, 26861, 26863, 26879, 26881, -26891, 26893, 26903, 26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987, -26993, 27011, 27017, 27031, 27043, 27059, 27061, 27067, 27073, 27077, 27091, -27103, 27107, 27109, 27127, 27143, 27179, 27191, 27197, 27211, 27239, 27241, -27253, 27259, 27271, 27277, 27281, 27283, 27299, 27329, 27337, 27361, 27367, -27397, 27407, 27409, 27427, 27431, 27437, 27449, 27457, 27479, 27481, 27487, -27509, 27527, 27529, 27539, 27541, 27551, 27581, 27583, 27611, 27617, 27631, -27647, 27653, 27673, 27689, 27691, 27697, 27701, 27733, 27737, 27739, 27743, -27749, 27751, 27763, 27767, 27773, 27779, 27791, 27793, 27799, 27803, 27809, -27817, 27823, 27827, 27847, 27851, 27883, 27893, 27901, 27917, 27919, 27941, -27943, 27947, 27953, 27961, 27967, 27983, 27997, 28001, 28019, 28027, 28031, -28051, 28057, 28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123, 28151, -28163, 28181, 28183, 28201, 28211, 28219, 28229, 28277, 28279, 28283, 28289, -28297, 28307, 28309, 28319, 28349, 28351, 28387, 28393, 28403, 28409, 28411, -28429, 28433, 28439, 28447, 28463, 28477, 28493, 28499, 28513, 28517, 28537, -28541, 28547, 28549, 28559, 28571, 28573, 28579, 28591, 28597, 28603, 28607, -28619, 28621, 28627, 28631, 28643, 28649, 28657, 28661, 28663, 28669, 28687, -28697, 28703, 28711, 28723, 28729, 28751, 28753, 28759, 28771, 28789, 28793, -28807, 28813, 28817, 28837, 28843, 28859, 28867, 28871, 28879, 28901, 28909, -28921, 28927, 28933, 28949, 28961, 28979, 29009, 29017, 29021, 29023, 29027, -29033, 29059, 29063, 29077, 29101, 29123, 29129, 29131, 29137, 29147, 29153, -29167, 29173, 29179, 29191, 29201, 29207, 29209, 29221, 29231, 29243, 29251, -29269, 29287, 29297, 29303, 29311, 29327, 29333, 29339, 29347, 29363, 29383, -29387, 29389, 29399, 29401, 29411, 29423, 29429, 29437, 29443, 29453, 29473, -29483, 29501, 29527, 29531, 29537, 29567, 29569, 29573, 29581, 29587, 29599, -29611, 29629, 29633, 29641, 29663, 29669, 29671, 29683, 29717, 29723, 29741, -29753, 29759, 29761, 29789, 29803, 29819, 29833, 29837, 29851, 29863, 29867, -29873, 29879, 29881, 29917, 29921, 29927, 29947, 29959, 29983, 29989, 30011, -30013, 30029, 30047, 30059, 30071, 30089, 30091, 30097, 30103, 30109, 30113, -30119, 30133, 30137, 30139, 30161, 30169, 30181, 30187, 30197, 30203, 30211, -30223, 30241, 30253, 30259, 30269, 30271, 30293, 30307, 30313, 30319, 30323, -30341, 30347, 30367, 30389, 30391, 30403, 30427, 30431, 30449, 30467, 30469, -30491, 30493, 30497, 30509, 30517, 30529, 30539, 30553, 30557, 30559, 30577, -30593, 30631, 30637, 30643, 30649, 30661, 30671, 30677, 30689, 30697, 30703, -30707, 30713, 30727, 30757, 30763, 30773, 30781, 30803, 30809, 30817, 30829, -30839, 30841, 30851, 30853, 30859, 30869, 30871, 30881, 30893, 30911, 30931, -30937, 30941, 30949, 30971, 30977, 30983, 31013, 31019, 31033, 31039, 31051, -31063, 31069, 31079, 31081, 31091, 31121, 31123, 31139, 31147, 31151, 31153, -31159, 31177, 31181, 31183, 31189, 31193, 31219, 31223, 31231, 31237, 31247, -31249, 31253, 31259, 31267, 31271, 31277, 31307, 31319, 31321, 31327, 31333, -31337, 31357, 31379, 31387, 31391, 31393, 31397, 31469, 31477, 31481, 31489, -31511, 31513, 31517, 31531, 31541, 31543, 31547, 31567, 31573, 31583, 31601, -31607, 31627, 31643, 31649, 31657, 31663, 31667, 31687, 31699, 31721, 31723, -31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817, 31847, 31849, -31859, 31873, 31883, 31891, 31907, 31957, 31963, 31973, 31981, 31991, 32003, -32009, 32027, 32029, 32051, 32057, 32059, 32063, 32069, 32077, 32083, 32089, -32099, 32117, 32119, 32141, 32143, 32159, 32173, 32183, 32189, 32191, 32203, -32213, 32233, 32237, 32251, 32257, 32261, 32297, 32299, 32303, 32309, 32321, -32323, 32327, 32341, 32353, 32359, 32363, 32369, 32371, 32377, 32381, 32401, -32411, 32413, 32423, 32429, 32441, 32443, 32467, 32479, 32491, 32497, 32503, -32507, 32531, 32533, 32537, 32561, 32563, 32569, 32573, 32579, 32587, 32603, -32609, 32611, 32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717, -32719, 32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803, 32831, 32833, -32839, 32843, 32869, 32887, 32909, 32911, 32917, 32933, 32939, 32941, 32957, -32969, 32971, 32983, 32987, 32993, 32999, 33013, 33023, 33029, 33037, 33049, -33053, 33071, 33073, 33083, 33091, 33107, 33113, 33119, 33149, 33151, 33161, -33179, 33181, 33191, 33199, 33203, 33211, 33223, 33247, 33287, 33289, 33301, -33311, 33317, 33329, 33331, 33343, 33347, 33349, 33353, 33359, 33377, 33391, -33403, 33409, 33413, 33427, 33457, 33461, 33469, 33479, 33487, 33493, 33503, -33521, 33529, 33533, 33547, 33563, 33569, 33577, 33581, 33587, 33589, 33599, -33601, 33613, 33617, 33619, 33623, 33629, 33637, 33641, 33647, 33679, 33703, -33713, 33721, 33739, 33749, 33751, 33757, 33767, 33769, 33773, 33791, 33797, -33809, 33811, 33827, 33829, 33851, 33857, 33863, 33871, 33889, 33893, 33911, -33923, 33931, 33937, 33941, 33961, 33967, 33997, 34019, 34031, 34033, 34039, -34057, 34061, 34123, 34127, 34129, 34141, 34147, 34157, 34159, 34171, 34183, -34211, 34213, 34217, 34231, 34253, 34259, 34261, 34267, 34273, 34283, 34297, -34301, 34303, 34313, 34319, 34327, 34337, 34351, 34361, 34367, 34369, 34381, -34403, 34421, 34429, 34439, 34457, 34469, 34471, 34483, 34487, 34499, 34501, -34511, 34513, 34519, 34537, 34543, 34549, 34583, 34589, 34591, 34603, 34607, -34613, 34631, 34649, 34651, 34667, 34673, 34679, 34687, 34693, 34703, 34721, -34729, 34739, 34747, 34757, 34759, 34763, 34781, 34807, 34819, 34841, 34843, -34847, 34849, 34871, 34877, 34883, 34897, 34913, 34919, 34939, 34949, 34961, -34963, 34981, 35023, 35027, 35051, 35053, 35059, 35069, 35081, 35083, 35089, -35099, 35107, 35111, 35117, 35129, 35141, 35149, 35153, 35159, 35171, 35201, -35221, 35227, 35251, 35257, 35267, 35279, 35281, 35291, 35311, 35317, 35323, -35327, 35339, 35353, 35363, 35381, 35393, 35401, 35407, 35419, 35423, 35437, -35447, 35449, 35461, 35491, 35507, 35509, 35521, 35527, 35531, 35533, 35537, -35543, 35569, 35573, 35591, 35593, 35597, 35603, 35617, 35671, 35677, 35729, -35731, 35747, 35753, 35759, 35771, 35797, 35801, 35803, 35809, 35831, 35837, -35839, 35851, 35863, 35869, 35879, 35897, 35899, 35911, 35923, 35933, 35951, -35963, 35969, 35977, 35983, 35993, 35999, 36007, 36011, 36013, 36017, 36037, -36061, 36067, 36073, 36083, 36097, 36107, 36109, 36131, 36137, 36151, 36161, -36187, 36191, 36209, 36217, 36229, 36241, 36251, 36263, 36269, 36277, 36293, -36299, 36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383, 36389, 36433, -36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497, 36523, 36527, 36529, -36541, 36551, 36559, 36563, 36571, 36583, 36587, 36599, 36607, 36629, 36637, -36643, 36653, 36671, 36677, 36683, 36691, 36697, 36709, 36713, 36721, 36739, -36749, 36761, 36767, 36779, 36781, 36787, 36791, 36793, 36809, 36821, 36833, -36847, 36857, 36871, 36877, 36887, 36899, 36901, 36913, 36919, 36923, 36929, -36931, 36943, 36947, 36973, 36979, 36997, 37003, 37013, 37019, 37021, 37039, -37049, 37057, 37061, 37087, 37097, 37117, 37123, 37139, 37159, 37171, 37181, -37189, 37199, 37201, 37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309, -37313, 37321, 37337, 37339, 37357, 37361, 37363, 37369, 37379, 37397, 37409, -37423, 37441, 37447, 37463, 37483, 37489, 37493, 37501, 37507, 37511, 37517, -37529, 37537, 37547, 37549, 37561, 37567, 37571, 37573, 37579, 37589, 37591, -37607, 37619, 37633, 37643, 37649, 37657, 37663, 37691, 37693, 37699, 37717, -37747, 37781, 37783, 37799, 37811, 37813, 37831, 37847, 37853, 37861, 37871, -37879, 37889, 37897, 37907, 37951, 37957, 37963, 37967, 37987, 37991, 37993, -37997, 38011, 38039, 38047, 38053, 38069, 38083, 38113, 38119, 38149, 38153, -38167, 38177, 38183, 38189, 38197, 38201, 38219, 38231, 38237, 38239, 38261, -38273, 38281, 38287, 38299, 38303, 38317, 38321, 38327, 38329, 38333, 38351, -38371, 38377, 38393, 38431, 38447, 38449, 38453, 38459, 38461, 38501, 38543, -38557, 38561, 38567, 38569, 38593, 38603, 38609, 38611, 38629, 38639, 38651, -38653, 38669, 38671, 38677, 38693, 38699, 38707, 38711, 38713, 38723, 38729, -38737, 38747, 38749, 38767, 38783, 38791, 38803, 38821, 38833, 38839, 38851, -38861, 38867, 38873, 38891, 38903, 38917, 38921, 38923, 38933, 38953, 38959, -38971, 38977, 38993, 39019, 39023, 39041, 39043, 39047, 39079, 39089, 39097, -39103, 39107, 39113, 39119, 39133, 39139, 39157, 39161, 39163, 39181, 39191, -39199, 39209, 39217, 39227, 39229, 39233, 39239, 39241, 39251, 39293, 39301, -39313, 39317, 39323, 39341, 39343, 39359, 39367, 39371, 39373, 39383, 39397, -39409, 39419, 39439, 39443, 39451, 39461, 39499, 39503, 39509, 39511, 39521, -39541, 39551, 39563, 39569, 39581, 39607, 39619, 39623, 39631, 39659, 39667, -39671, 39679, 39703, 39709, 39719, 39727, 39733, 39749, 39761, 39769, 39779, -39791, 39799, 39821, 39827, 39829, 39839, 39841, 39847, 39857, 39863, 39869, -39877, 39883, 39887, 39901, 39929, 39937, 39953, 39971, 39979, 39983, 39989, -40009, 40013, 40031, 40037, 40039, 40063, 40087, 40093, 40099, 40111, 40123, -40127, 40129, 40151, 40153, 40163, 40169, 40177, 40189, 40193, 40213, 40231, -40237, 40241, 40253, 40277, 40283, 40289, 40343, 40351, 40357, 40361, 40387, -40423, 40427, 40429, 40433, 40459, 40471, 40483, 40487, 40493, 40499, 40507, -40519, 40529, 40531, 40543, 40559, 40577, 40583, 40591, 40597, 40609, 40627, -40637, 40639, 40693, 40697, 40699, 40709, 40739, 40751, 40759, 40763, 40771, -40787, 40801, 40813, 40819, 40823, 40829, 40841, 40847, 40849, 40853, 40867, -40879, 40883, 40897, 40903, 40927, 40933, 40939, 40949, 40961, 40973, 40993, -41011, 41017, 41023, 41039, 41047, 41051, 41057, 41077, 41081, 41113, 41117, -41131, 41141, 41143, 41149, 41161, 41177, 41179, 41183, 41189, 41201, 41203, -41213, 41221, 41227, 41231, 41233, 41243, 41257, 41263, 41269, 41281, 41299, -41333, 41341, 41351, 41357, 41381, 41387, 41389, 41399, 41411, 41413, 41443, -41453, 41467, 41479, 41491, 41507, 41513, 41519, 41521, 41539, 41543, 41549, -41579, 41593, 41597, 41603, 41609, 41611, 41617, 41621, 41627, 41641, 41647, -41651, 41659, 41669, 41681, 41687, 41719, 41729, 41737, 41759, 41761, 41771, -41777, 41801, 41809, 41813, 41843, 41849, 41851, 41863, 41879, 41887, 41893, -41897, 41903, 41911, 41927, 41941, 41947, 41953, 41957, 41959, 41969, 41981, -41983, 41999, 42013, 42017, 42019, 42023, 42043, 42061, 42071, 42073, 42083, -42089, 42101, 42131, 42139, 42157, 42169, 42179, 42181, 42187, 42193, 42197, -42209, 42221, 42223, 42227, 42239, 42257, 42281, 42283, 42293, 42299, 42307, -42323, 42331, 42337, 42349, 42359, 42373, 42379, 42391, 42397, 42403, 42407, -42409, 42433, 42437, 42443, 42451, 42457, 42461, 42463, 42467, 42473, 42487, -42491, 42499, 42509, 42533, 42557, 42569, 42571, 42577, 42589, 42611, 42641, -42643, 42649, 42667, 42677, 42683, 42689, 42697, 42701, 42703, 42709, 42719, -42727, 42737, 42743, 42751, 42767, 42773, 42787, 42793, 42797, 42821, 42829, -42839, 42841, 42853, 42859, 42863, 42899, 42901, 42923, 42929, 42937, 42943, -42953, 42961, 42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, 43051, -43063, 43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177, 43189, 43201, -43207, 43223, 43237, 43261, 43271, 43283, 43291, 43313, 43319, 43321, 43331, -43391, 43397, 43399, 43403, 43411, 43427, 43441, 43451, 43457, 43481, 43487, -43499, 43517, 43541, 43543, 43573, 43577, 43579, 43591, 43597, 43607, 43609, -43613, 43627, 43633, 43649, 43651, 43661, 43669, 43691, 43711, 43717, 43721, -43753, 43759, 43777, 43781, 43783, 43787, 43789, 43793, 43801, 43853, 43867, -43889, 43891, 43913, 43933, 43943, 43951, 43961, 43963, 43969, 43973, 43987, -43991, 43997, 44017, 44021, 44027, 44029, 44041, 44053, 44059, 44071, 44087, -44089, 44101, 44111, 44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189, -44201, 44203, 44207, 44221, 44249, 44257, 44263, 44267, 44269, 44273, 44279, -44281, 44293, 44351, 44357, 44371, 44381, 44383, 44389, 44417, 44449, 44453, -44483, 44491, 44497, 44501, 44507, 44519, 44531, 44533, 44537, 44543, 44549, -44563, 44579, 44587, 44617, 44621, 44623, 44633, 44641, 44647, 44651, 44657, -44683, 44687, 44699, 44701, 44711, 44729, 44741, 44753, 44771, 44773, 44777, -44789, 44797, 44809, 44819, 44839, 44843, 44851, 44867, 44879, 44887, 44893, -44909, 44917, 44927, 44939, 44953, 44959, 44963, 44971, 44983, 44987, 45007, -45013, 45053, 45061, 45077, 45083, 45119, 45121, 45127, 45131, 45137, 45139, -45161, 45179, 45181, 45191, 45197, 45233, 45247, 45259, 45263, 45281, 45289, -45293, 45307, 45317, 45319, 45329, 45337, 45341, 45343, 45361, 45377, 45389, -45403, 45413, 45427, 45433, 45439, 45481, 45491, 45497, 45503, 45523, 45533, -45541, 45553, 45557, 45569, 45587, 45589, 45599, 45613, 45631, 45641, 45659, -45667, 45673, 45677, 45691, 45697, 45707, 45737, 45751, 45757, 45763, 45767, -45779, 45817, 45821, 45823, 45827, 45833, 45841, 45853, 45863, 45869, 45887, -45893, 45943, 45949, 45953, 45959, 45971, 45979, 45989, 46021, 46027, 46049, -46051, 46061, 46073, 46091, 46093, 46099, 46103, 46133, 46141, 46147, 46153, -46171, 46181, 46183, 46187, 46199, 46219, 46229, 46237, 46261, 46271, 46273, -46279, 46301, 46307, 46309, 46327, 46337, 46349, 46351, 46381, 46399, 46411, -46439, 46441, 46447, 46451, 46457, 46471, 46477, 46489, 46499, 46507, 46511, -46523, 46549, 46559, 46567, 46573, 46589, 46591, 46601, 46619, 46633, 46639, -46643, 46649, 46663, 46679, 46681, 46687, 46691, 46703, 46723, 46727, 46747, -46751, 46757, 46769, 46771, 46807, 46811, 46817, 46819, 46829, 46831, 46853, -46861, 46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993, 46997, 47017, -47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119, 47123, 47129, 47137, -47143, 47147, 47149, 47161, 47189, 47207, 47221, 47237, 47251, 47269, 47279, -47287, 47293, 47297, 47303, 47309, 47317, 47339, 47351, 47353, 47363, 47381, -47387, 47389, 47407, 47417, 47419, 47431, 47441, 47459, 47491, 47497, 47501, -47507, 47513, 47521, 47527, 47533, 47543, 47563, 47569, 47581, 47591, 47599, -47609, 47623, 47629, 47639, 47653, 47657, 47659, 47681, 47699, 47701, 47711, -47713, 47717, 47737, 47741, 47743, 47777, 47779, 47791, 47797, 47807, 47809, -47819, 47837, 47843, 47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939, -47947, 47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049, 48073, -48079, 48091, 48109, 48119, 48121, 48131, 48157, 48163, 48179, 48187, 48193, -48197, 48221, 48239, 48247, 48259, 48271, 48281, 48299, 48311, 48313, 48337, -48341, 48353, 48371, 48383, 48397, 48407, 48409, 48413, 48437, 48449, 48463, -48473, 48479, 48481, 48487, 48491, 48497, 48523, 48527, 48533, 48539, 48541, -48563, 48571, 48589, 48593, 48611, 48619, 48623, 48647, 48649, 48661, 48673, -48677, 48679, 48731, 48733, 48751, 48757, 48761, 48767, 48779, 48781, 48787, -48799, 48809, 48817, 48821, 48823, 48847, 48857, 48859, 48869, 48871, 48883, -48889, 48907, 48947, 48953, 48973, 48989, 48991, 49003, 49009, 49019, 49031, -49033, 49037, 49043, 49057, 49069, 49081, 49103, 49109, 49117, 49121, 49123, -49139, 49157, 49169, 49171, 49177, 49193, 49199, 49201, 49207, 49211, 49223, -49253, 49261, 49277, 49279, 49297, 49307, 49331, 49333, 49339, 49363, 49367, -49369, 49391, 49393, 49409, 49411, 49417, 49429, 49433, 49451, 49459, 49463, -49477, 49481, 49499, 49523, 49529, 49531, 49537, 49547, 49549, 49559, 49597, -49603, 49613, 49627, 49633, 49639, 49663, 49667, 49669, 49681, 49697, 49711, -49727, 49739, 49741, 49747, 49757, 49783, 49787, 49789, 49801, 49807, 49811, -49823, 49831, 49843, 49853, 49871, 49877, 49891, 49919, 49921, 49927, 49937, -49939, 49943, 49957, 49991, 49993, 49999, 50021, 50023, 50033, 50047, 50051, -50053, 50069, 50077, 50087, 50093, 50101, 50111, 50119, 50123, 50129, 50131, -50147, 50153, 50159, 50177, 50207, 50221, 50227, 50231, 50261, 50263, 50273, -50287, 50291, 50311, 50321, 50329, 50333, 50341, 50359, 50363, 50377, 50383, -50387, 50411, 50417, 50423, 50441, 50459, 50461, 50497, 50503, 50513, 50527, -50539, 50543, 50549, 50551, 50581, 50587, 50591, 50593, 50599, 50627, 50647, -50651, 50671, 50683, 50707, 50723, 50741, 50753, 50767, 50773, 50777, 50789, -50821, 50833, 50839, 50849, 50857, 50867, 50873, 50891, 50893, 50909, 50923, -50929, 50951, 50957, 50969, 50971, 50989, 50993, 51001, 51031, 51043, 51047, -51059, 51061, 51071, 51109, 51131, 51133, 51137, 51151, 51157, 51169, 51193, -51197, 51199, 51203, 51217, 51229, 51239, 51241, 51257, 51263, 51283, 51287, -51307, 51329, 51341, 51343, 51347, 51349, 51361, 51383, 51407, 51413, 51419, -51421, 51427, 51431, 51437, 51439, 51449, 51461, 51473, 51479, 51481, 51487, -51503, 51511, 51517, 51521, 51539, 51551, 51563, 51577, 51581, 51593, 51599, -51607, 51613, 51631, 51637, 51647, 51659, 51673, 51679, 51683, 51691, 51713, -51719, 51721, 51749, 51767, 51769, 51787, 51797, 51803, 51817, 51827, 51829, -51839, 51853, 51859, 51869, 51871, 51893, 51899, 51907, 51913, 51929, 51941, -51949, 51971, 51973, 51977, 51991, 52009, 52021, 52027, 52051, 52057, 52067, -52069, 52081, 52103, 52121, 52127, 52147, 52153, 52163, 52177, 52181, 52183, -52189, 52201, 52223, 52237, 52249, 52253, 52259, 52267, 52289, 52291, 52301, -52313, 52321, 52361, 52363, 52369, 52379, 52387, 52391, 52433, 52453, 52457, -52489, 52501, 52511, 52517, 52529, 52541, 52543, 52553, 52561, 52567, 52571, -52579, 52583, 52609, 52627, 52631, 52639, 52667, 52673, 52691, 52697, 52709, -52711, 52721, 52727, 52733, 52747, 52757, 52769, 52783, 52807, 52813, 52817, -52837, 52859, 52861, 52879, 52883, 52889, 52901, 52903, 52919, 52937, 52951, -52957, 52963, 52967, 52973, 52981, 52999, 53003, 53017, 53047, 53051, 53069, -53077, 53087, 53089, 53093, 53101, 53113, 53117, 53129, 53147, 53149, 53161, -53171, 53173, 53189, 53197, 53201, 53231, 53233, 53239, 53267, 53269, 53279, -53281, 53299, 53309, 53323, 53327, 53353, 53359, 53377, 53381, 53401, 53407, -53411, 53419, 53437, 53441, 53453, 53479, 53503, 53507, 53527, 53549, 53551, -53569, 53591, 53593, 53597, 53609, 53611, 53617, 53623, 53629, 53633, 53639, -53653, 53657, 53681, 53693, 53699, 53717, 53719, 53731, 53759, 53773, 53777, -53783, 53791, 53813, 53819, 53831, 53849, 53857, 53861, 53881, 53887, 53891, -53897, 53899, 53917, 53923, 53927, 53939, 53951, 53959, 53987, 53993, 54001, -54011, 54013, 54037, 54049, 54059, 54083, 54091, 54101, 54121, 54133, 54139, -54151, 54163, 54167, 54181, 54193, 54217, 54251, 54269, 54277, 54287, 54293, -54311, 54319, 54323, 54331, 54347, 54361, 54367, 54371, 54377, 54401, 54403, -54409, 54413, 54419, 54421, 54437, 54443, 54449, 54469, 54493, 54497, 54499, -54503, 54517, 54521, 54539, 54541, 54547, 54559, 54563, 54577, 54581, 54583, -54601, 54617, 54623, 54629, 54631, 54647, 54667, 54673, 54679, 54709, 54713, -54721, 54727, 54751, 54767, 54773, 54779, 54787, 54799, 54829, 54833, 54851, -54869, 54877, 54881, 54907, 54917, 54919, 54941, 54949, 54959, 54973, 54979, -54983, 55001, 55009, 55021, 55049, 55051, 55057, 55061, 55073, 55079, 55103, -55109, 55117, 55127, 55147, 55163, 55171, 55201, 55207, 55213, 55217, 55219, -55229, 55243, 55249, 55259, 55291, 55313, 55331, 55333, 55337, 55339, 55343, -55351, 55373, 55381, 55399, 55411, 55439, 55441, 55457, 55469, 55487, 55501, -55511, 55529, 55541, 55547, 55579, 55589, 55603, 55609, 55619, 55621, 55631, -55633, 55639, 55661, 55663, 55667, 55673, 55681, 55691, 55697, 55711, 55717, -55721, 55733, 55763, 55787, 55793, 55799, 55807, 55813, 55817, 55819, 55823, -55829, 55837, 55843, 55849, 55871, 55889, 55897, 55901, 55903, 55921, 55927, -55931, 55933, 55949, 55967, 55987, 55997, 56003, 56009, 56039, 56041, 56053, -56081, 56087, 56093, 56099, 56101, 56113, 56123, 56131, 56149, 56167, 56171, -56179, 56197, 56207, 56209, 56237, 56239, 56249, 56263, 56267, 56269, 56299, -56311, 56333, 56359, 56369, 56377, 56383, 56393, 56401, 56417, 56431, 56437, -56443, 56453, 56467, 56473, 56477, 56479, 56489, 56501, 56503, 56509, 56519, -56527, 56531, 56533, 56543, 56569, 56591, 56597, 56599, 56611, 56629, 56633, -56659, 56663, 56671, 56681, 56687, 56701, 56711, 56713, 56731, 56737, 56747, -56767, 56773, 56779, 56783, 56807, 56809, 56813, 56821, 56827, 56843, 56857, -56873, 56891, 56893, 56897, 56909, 56911, 56921, 56923, 56929, 56941, 56951, -56957, 56963, 56983, 56989, 56993, 56999, 57037, 57041, 57047, 57059, 57073, -57077, 57089, 57097, 57107, 57119, 57131, 57139, 57143, 57149, 57163, 57173, -57179, 57191, 57193, 57203, 57221, 57223, 57241, 57251, 57259, 57269, 57271, -57283, 57287, 57301, 57329, 57331, 57347, 57349, 57367, 57373, 57383, 57389, -57397, 57413, 57427, 57457, 57467, 57487, 57493, 57503, 57527, 57529, 57557, -57559, 57571, 57587, 57593, 57601, 57637, 57641, 57649, 57653, 57667, 57679, -57689, 57697, 57709, 57713, 57719, 57727, 57731, 57737, 57751, 57773, 57781, -57787, 57791, 57793, 57803, 57809, 57829, 57839, 57847, 57853, 57859, 57881, -57899, 57901, 57917, 57923, 57943, 57947, 57973, 57977, 57991, 58013, 58027, -58031, 58043, 58049, 58057, 58061, 58067, 58073, 58099, 58109, 58111, 58129, -58147, 58151, 58153, 58169, 58171, 58189, 58193, 58199, 58207, 58211, 58217, -58229, 58231, 58237, 58243, 58271, 58309, 58313, 58321, 58337, 58363, 58367, -58369, 58379, 58391, 58393, 58403, 58411, 58417, 58427, 58439, 58441, 58451, -58453, 58477, 58481, 58511, 58537, 58543, 58549, 58567, 58573, 58579, 58601, -58603, 58613, 58631, 58657, 58661, 58679, 58687, 58693, 58699, 58711, 58727, -58733, 58741, 58757, 58763, 58771, 58787, 58789, 58831, 58889, 58897, 58901, -58907, 58909, 58913, 58921, 58937, 58943, 58963, 58967, 58979, 58991, 58997, -59009, 59011, 59021, 59023, 59029, 59051, 59053, 59063, 59069, 59077, 59083, -59093, 59107, 59113, 59119, 59123, 59141, 59149, 59159, 59167, 59183, 59197, -59207, 59209, 59219, 59221, 59233, 59239, 59243, 59263, 59273, 59281, 59333, -59341, 59351, 59357, 59359, 59369, 59377, 59387, 59393, 59399, 59407, 59417, -59419, 59441, 59443, 59447, 59453, 59467, 59471, 59473, 59497, 59509, 59513, -59539, 59557, 59561, 59567, 59581, 59611, 59617, 59621, 59627, 59629, 59651, -59659, 59663, 59669, 59671, 59693, 59699, 59707, 59723, 59729, 59743, 59747, -59753, 59771, 59779, 59791, 59797, 59809, 59833, 59863, 59879, 59887, 59921, -59929, 59951, 59957, 59971, 59981, 59999, 60013, 60017, 60029, 60037, 60041, -60077, 60083, 60089, 60091, 60101, 60103, 60107, 60127, 60133, 60139, 60149, -60161, 60167, 60169, 60209, 60217, 60223, 60251, 60257, 60259, 60271, 60289, -60293, 60317, 60331, 60337, 60343, 60353, 60373, 60383, 60397, 60413, 60427, -60443, 60449, 60457, 60493, 60497, 60509, 60521, 60527, 60539, 60589, 60601, -60607, 60611, 60617, 60623, 60631, 60637, 60647, 60649, 60659, 60661, 60679, -60689, 60703, 60719, 60727, 60733, 60737, 60757, 60761, 60763, 60773, 60779, -60793, 60811, 60821, 60859, 60869, 60887, 60889, 60899, 60901, 60913, 60917, -60919, 60923, 60937, 60943, 60953, 60961, 61001, 61007, 61027, 61031, 61043, -61051, 61057, 61091, 61099, 61121, 61129, 61141, 61151, 61153, 61169, 61211, -61223, 61231, 61253, 61261, 61283, 61291, 61297, 61331, 61333, 61339, 61343, -61357, 61363, 61379, 61381, 61403, 61409, 61417, 61441, 61463, 61469, 61471, -61483, 61487, 61493, 61507, 61511, 61519, 61543, 61547, 61553, 61559, 61561, -61583, 61603, 61609, 61613, 61627, 61631, 61637, 61643, 61651, 61657, 61667, -61673, 61681, 61687, 61703, 61717, 61723, 61729, 61751, 61757, 61781, 61813, -61819, 61837, 61843, 61861, 61871, 61879, 61909, 61927, 61933, 61949, 61961, -61967, 61979, 61981, 61987, 61991, 62003, 62011, 62017, 62039, 62047, 62053, -62057, 62071, 62081, 62099, 62119, 62129, 62131, 62137, 62141, 62143, 62171, -62189, 62191, 62201, 62207, 62213, 62219, 62233, 62273, 62297, 62299, 62303, -62311, 62323, 62327, 62347, 62351, 62383, 62401, 62417, 62423, 62459, 62467, -62473, 62477, 62483, 62497, 62501, 62507, 62533, 62539, 62549, 62563, 62581, -62591, 62597, 62603, 62617, 62627, 62633, 62639, 62653, 62659, 62683, 62687, -62701, 62723, 62731, 62743, 62753, 62761, 62773, 62791, 62801, 62819, 62827, -62851, 62861, 62869, 62873, 62897, 62903, 62921, 62927, 62929, 62939, 62969, -62971, 62981, 62983, 62987, 62989, 63029, 63031, 63059, 63067, 63073, 63079, -63097, 63103, 63113, 63127, 63131, 63149, 63179, 63197, 63199, 63211, 63241, -63247, 63277, 63281, 63299, 63311, 63313, 63317, 63331, 63337, 63347, 63353, -63361, 63367, 63377, 63389, 63391, 63397, 63409, 63419, 63421, 63439, 63443, -63463, 63467, 63473, 63487, 63493, 63499, 63521, 63527, 63533, 63541, 63559, -63577, 63587, 63589, 63599, 63601, 63607, 63611, 63617, 63629, 63647, 63649, -63659, 63667, 63671, 63689, 63691, 63697, 63703, 63709, 63719, 63727, 63737, -63743, 63761, 63773, 63781, 63793, 63799, 63803, 63809, 63823, 63839, 63841, -63853, 63857, 63863, 63901, 63907, 63913, 63929, 63949, 63977, 63997, 64007, -64013, 64019, 64033, 64037, 64063, 64067, 64081, 64091, 64109, 64123, 64151, -64153, 64157, 64171, 64187, 64189, 64217, 64223, 64231, 64237, 64271, 64279, -64283, 64301, 64303, 64319, 64327, 64333, 64373, 64381, 64399, 64403, 64433, -64439, 64451, 64453, 64483, 64489, 64499, 64513, 64553, 64567, 64577, 64579, -64591, 64601, 64609, 64613, 64621, 64627, 64633, 64661, 64663, 64667, 64679, -64693, 64709, 64717, 64747, 64763, 64781, 64783, 64793, 64811, 64817, 64849, -64853, 64871, 64877, 64879, 64891, 64901, 64919, 64921, 64927, 64937, 64951, -64969, 64997, 65003, 65011, 65027, 65029, 65033, 65053, 65063, 65071, 65089, -65099, 65101, 65111, 65119, 65123, 65129, 65141, 65147, 65167, 65171, 65173, -65179, 65183, 65203, 65213, 65239, 65257, 65267, 65269, 65287, 65293, 65309, -65323, 65327, 65353, 65357, 65371, 65381, 65393, 65407, 65413, 65419, 65423, -65437, 65447, 65449, 65479, 65497, 65519, 65521, 0 }; +const uint16_t PRIMES[PRIME_TABLE_SIZE + 1] = { + 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, + 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, + 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, + 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, + 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, + 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, + 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, + 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, + 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, + 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, + 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, + 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, + 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, + 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, + 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, + 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, + 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, + 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, + 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, + 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, + 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, + 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, + 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, + 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, + 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, + 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, + 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, + 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, + 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, + 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, + 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, + 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, + 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, + 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, + 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, + 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, + 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, + 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, + 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, + 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, + 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, + 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, + 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, + 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, + 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, + 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, + 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, + 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, + 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, + 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, + 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, + 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, + 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, + 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, + 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, + 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, + 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, + 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, + 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, + 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, + 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, + 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, + 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, + 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, + 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, + 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, + 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, + 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, + 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, + 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, + 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, + 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, + 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, + 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, + 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, + 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, + 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, + 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, + 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, + 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, + 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, + 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, + 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, + 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, + 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, + 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, + 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, + 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, + 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, + 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, + 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, + 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, + 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, 10039, 10061, 10067, 10069, + 10079, 10091, 10093, 10099, 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, + 10177, 10181, 10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271, 10273, 10289, + 10301, 10303, 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, + 10429, 10433, 10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, + 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, 10657, 10663, + 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, 10781, 10789, + 10799, 10831, 10837, 10847, 10853, 10859, 10861, 10867, 10883, 10889, 10891, 10903, 10909, + 10937, 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, + 11069, 11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171, + 11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279, 11287, 11299, + 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, 11411, 11423, 11437, + 11443, 11447, 11467, 11471, 11483, 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, + 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, 11677, 11681, 11689, 11699, 11701, + 11717, 11719, 11731, 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, + 11831, 11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939, + 11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037, 12041, 12043, 12049, + 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, 12163, + 12197, 12203, 12211, 12227, 12239, 12241, 12251, 12253, 12263, 12269, 12277, 12281, 12289, + 12301, 12323, 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, + 12433, 12437, 12451, 12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, + 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619, 12637, + 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, 12743, 12757, + 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, 12841, 12853, 12889, 12893, 12899, + 12907, 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001, + 13003, 13007, 13009, 13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, + 13127, 13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229, 13241, + 13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, 13339, 13367, 13381, + 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, + 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, 13613, 13619, 13627, 13633, 13649, + 13669, 13679, 13681, 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, + 13757, 13759, 13763, 13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, + 13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, 13997, 13999, + 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, 14149, + 14153, 14159, 14173, 14177, 14197, 14207, 14221, 14243, 14249, 14251, 14281, 14293, 14303, + 14321, 14323, 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, + 14431, 14437, 14447, 14449, 14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, + 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653, 14657, + 14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, 14759, 14767, + 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, 14851, 14867, 14869, 14879, + 14887, 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, 14969, 14983, 15013, 15017, + 15031, 15053, 15061, 15073, 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, + 15149, 15161, 15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269, + 15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349, 15359, 15361, + 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, + 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, 15581, 15583, 15601, 15607, 15619, + 15629, 15641, 15643, 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, 15731, 15733, + 15737, 15739, 15749, 15761, 15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, + 15859, 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, + 15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, 16091, + 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187, 16189, 16193, 16217, 16223, 16229, + 16231, 16249, 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, 16361, 16363, 16369, + 16381, 16411, 16417, 16421, 16427, 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, + 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649, + 16651, 16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 16759, 16763, + 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889, 16901, 16903, 16921, + 16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, 17011, 17021, 17027, 17029, + 17033, 17041, 17047, 17053, 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, 17167, + 17183, 17189, 17191, 17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, + 17321, 17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401, 17417, + 17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, + 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 17609, 17623, 17627, 17657, 17659, + 17669, 17681, 17683, 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, 17789, 17791, + 17807, 17827, 17837, 17839, 17851, 17863, 17881, 17891, 17903, 17909, 17911, 17921, 17923, + 17929, 17939, 17957, 17959, 17971, 17977, 17981, 17987, 17989, 18013, 18041, 18043, 18047, + 18049, 18059, 18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133, 18143, 18149, + 18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233, 18251, 18253, 18257, 18269, + 18287, 18289, 18301, 18307, 18311, 18313, 18329, 18341, 18353, 18367, 18371, 18379, 18397, + 18401, 18413, 18427, 18433, 18439, 18443, 18451, 18457, 18461, 18481, 18493, 18503, 18517, + 18521, 18523, 18539, 18541, 18553, 18583, 18587, 18593, 18617, 18637, 18661, 18671, 18679, + 18691, 18701, 18713, 18719, 18731, 18743, 18749, 18757, 18773, 18787, 18793, 18797, 18803, + 18839, 18859, 18869, 18899, 18911, 18913, 18917, 18919, 18947, 18959, 18973, 18979, 19001, + 19009, 19013, 19031, 19037, 19051, 19069, 19073, 19079, 19081, 19087, 19121, 19139, 19141, + 19157, 19163, 19181, 19183, 19207, 19211, 19213, 19219, 19231, 19237, 19249, 19259, 19267, + 19273, 19289, 19301, 19309, 19319, 19333, 19373, 19379, 19381, 19387, 19391, 19403, 19417, + 19421, 19423, 19427, 19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477, 19483, + 19489, 19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571, 19577, 19583, 19597, 19603, + 19609, 19661, 19681, 19687, 19697, 19699, 19709, 19717, 19727, 19739, 19751, 19753, 19759, + 19763, 19777, 19793, 19801, 19813, 19819, 19841, 19843, 19853, 19861, 19867, 19889, 19891, + 19913, 19919, 19927, 19937, 19949, 19961, 19963, 19973, 19979, 19991, 19993, 19997, 20011, + 20021, 20023, 20029, 20047, 20051, 20063, 20071, 20089, 20101, 20107, 20113, 20117, 20123, + 20129, 20143, 20147, 20149, 20161, 20173, 20177, 20183, 20201, 20219, 20231, 20233, 20249, + 20261, 20269, 20287, 20297, 20323, 20327, 20333, 20341, 20347, 20353, 20357, 20359, 20369, + 20389, 20393, 20399, 20407, 20411, 20431, 20441, 20443, 20477, 20479, 20483, 20507, 20509, + 20521, 20533, 20543, 20549, 20551, 20563, 20593, 20599, 20611, 20627, 20639, 20641, 20663, + 20681, 20693, 20707, 20717, 20719, 20731, 20743, 20747, 20749, 20753, 20759, 20771, 20773, + 20789, 20807, 20809, 20849, 20857, 20873, 20879, 20887, 20897, 20899, 20903, 20921, 20929, + 20939, 20947, 20959, 20963, 20981, 20983, 21001, 21011, 21013, 21017, 21019, 21023, 21031, + 21059, 21061, 21067, 21089, 21101, 21107, 21121, 21139, 21143, 21149, 21157, 21163, 21169, + 21179, 21187, 21191, 21193, 21211, 21221, 21227, 21247, 21269, 21277, 21283, 21313, 21317, + 21319, 21323, 21341, 21347, 21377, 21379, 21383, 21391, 21397, 21401, 21407, 21419, 21433, + 21467, 21481, 21487, 21491, 21493, 21499, 21503, 21517, 21521, 21523, 21529, 21557, 21559, + 21563, 21569, 21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647, 21649, 21661, + 21673, 21683, 21701, 21713, 21727, 21737, 21739, 21751, 21757, 21767, 21773, 21787, 21799, + 21803, 21817, 21821, 21839, 21841, 21851, 21859, 21863, 21871, 21881, 21893, 21911, 21929, + 21937, 21943, 21961, 21977, 21991, 21997, 22003, 22013, 22027, 22031, 22037, 22039, 22051, + 22063, 22067, 22073, 22079, 22091, 22093, 22109, 22111, 22123, 22129, 22133, 22147, 22153, + 22157, 22159, 22171, 22189, 22193, 22229, 22247, 22259, 22271, 22273, 22277, 22279, 22283, + 22291, 22303, 22307, 22343, 22349, 22367, 22369, 22381, 22391, 22397, 22409, 22433, 22441, + 22447, 22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543, 22549, 22567, 22571, + 22573, 22613, 22619, 22621, 22637, 22639, 22643, 22651, 22669, 22679, 22691, 22697, 22699, + 22709, 22717, 22721, 22727, 22739, 22741, 22751, 22769, 22777, 22783, 22787, 22807, 22811, + 22817, 22853, 22859, 22861, 22871, 22877, 22901, 22907, 22921, 22937, 22943, 22961, 22963, + 22973, 22993, 23003, 23011, 23017, 23021, 23027, 23029, 23039, 23041, 23053, 23057, 23059, + 23063, 23071, 23081, 23087, 23099, 23117, 23131, 23143, 23159, 23167, 23173, 23189, 23197, + 23201, 23203, 23209, 23227, 23251, 23269, 23279, 23291, 23293, 23297, 23311, 23321, 23327, + 23333, 23339, 23357, 23369, 23371, 23399, 23417, 23431, 23447, 23459, 23473, 23497, 23509, + 23531, 23537, 23539, 23549, 23557, 23561, 23563, 23567, 23581, 23593, 23599, 23603, 23609, + 23623, 23627, 23629, 23633, 23663, 23669, 23671, 23677, 23687, 23689, 23719, 23741, 23743, + 23747, 23753, 23761, 23767, 23773, 23789, 23801, 23813, 23819, 23827, 23831, 23833, 23857, + 23869, 23873, 23879, 23887, 23893, 23899, 23909, 23911, 23917, 23929, 23957, 23971, 23977, + 23981, 23993, 24001, 24007, 24019, 24023, 24029, 24043, 24049, 24061, 24071, 24077, 24083, + 24091, 24097, 24103, 24107, 24109, 24113, 24121, 24133, 24137, 24151, 24169, 24179, 24181, + 24197, 24203, 24223, 24229, 24239, 24247, 24251, 24281, 24317, 24329, 24337, 24359, 24371, + 24373, 24379, 24391, 24407, 24413, 24419, 24421, 24439, 24443, 24469, 24473, 24481, 24499, + 24509, 24517, 24527, 24533, 24547, 24551, 24571, 24593, 24611, 24623, 24631, 24659, 24671, + 24677, 24683, 24691, 24697, 24709, 24733, 24749, 24763, 24767, 24781, 24793, 24799, 24809, + 24821, 24841, 24847, 24851, 24859, 24877, 24889, 24907, 24917, 24919, 24923, 24943, 24953, + 24967, 24971, 24977, 24979, 24989, 25013, 25031, 25033, 25037, 25057, 25073, 25087, 25097, + 25111, 25117, 25121, 25127, 25147, 25153, 25163, 25169, 25171, 25183, 25189, 25219, 25229, + 25237, 25243, 25247, 25253, 25261, 25301, 25303, 25307, 25309, 25321, 25339, 25343, 25349, + 25357, 25367, 25373, 25391, 25409, 25411, 25423, 25439, 25447, 25453, 25457, 25463, 25469, + 25471, 25523, 25537, 25541, 25561, 25577, 25579, 25583, 25589, 25601, 25603, 25609, 25621, + 25633, 25639, 25643, 25657, 25667, 25673, 25679, 25693, 25703, 25717, 25733, 25741, 25747, + 25759, 25763, 25771, 25793, 25799, 25801, 25819, 25841, 25847, 25849, 25867, 25873, 25889, + 25903, 25913, 25919, 25931, 25933, 25939, 25943, 25951, 25969, 25981, 25997, 25999, 26003, + 26017, 26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111, 26113, 26119, 26141, 26153, + 26161, 26171, 26177, 26183, 26189, 26203, 26209, 26227, 26237, 26249, 26251, 26261, 26263, + 26267, 26293, 26297, 26309, 26317, 26321, 26339, 26347, 26357, 26371, 26387, 26393, 26399, + 26407, 26417, 26423, 26431, 26437, 26449, 26459, 26479, 26489, 26497, 26501, 26513, 26539, + 26557, 26561, 26573, 26591, 26597, 26627, 26633, 26641, 26647, 26669, 26681, 26683, 26687, + 26693, 26699, 26701, 26711, 26713, 26717, 26723, 26729, 26731, 26737, 26759, 26777, 26783, + 26801, 26813, 26821, 26833, 26839, 26849, 26861, 26863, 26879, 26881, 26891, 26893, 26903, + 26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987, 26993, 27011, 27017, 27031, 27043, + 27059, 27061, 27067, 27073, 27077, 27091, 27103, 27107, 27109, 27127, 27143, 27179, 27191, + 27197, 27211, 27239, 27241, 27253, 27259, 27271, 27277, 27281, 27283, 27299, 27329, 27337, + 27361, 27367, 27397, 27407, 27409, 27427, 27431, 27437, 27449, 27457, 27479, 27481, 27487, + 27509, 27527, 27529, 27539, 27541, 27551, 27581, 27583, 27611, 27617, 27631, 27647, 27653, + 27673, 27689, 27691, 27697, 27701, 27733, 27737, 27739, 27743, 27749, 27751, 27763, 27767, + 27773, 27779, 27791, 27793, 27799, 27803, 27809, 27817, 27823, 27827, 27847, 27851, 27883, + 27893, 27901, 27917, 27919, 27941, 27943, 27947, 27953, 27961, 27967, 27983, 27997, 28001, + 28019, 28027, 28031, 28051, 28057, 28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123, + 28151, 28163, 28181, 28183, 28201, 28211, 28219, 28229, 28277, 28279, 28283, 28289, 28297, + 28307, 28309, 28319, 28349, 28351, 28387, 28393, 28403, 28409, 28411, 28429, 28433, 28439, + 28447, 28463, 28477, 28493, 28499, 28513, 28517, 28537, 28541, 28547, 28549, 28559, 28571, + 28573, 28579, 28591, 28597, 28603, 28607, 28619, 28621, 28627, 28631, 28643, 28649, 28657, + 28661, 28663, 28669, 28687, 28697, 28703, 28711, 28723, 28729, 28751, 28753, 28759, 28771, + 28789, 28793, 28807, 28813, 28817, 28837, 28843, 28859, 28867, 28871, 28879, 28901, 28909, + 28921, 28927, 28933, 28949, 28961, 28979, 29009, 29017, 29021, 29023, 29027, 29033, 29059, + 29063, 29077, 29101, 29123, 29129, 29131, 29137, 29147, 29153, 29167, 29173, 29179, 29191, + 29201, 29207, 29209, 29221, 29231, 29243, 29251, 29269, 29287, 29297, 29303, 29311, 29327, + 29333, 29339, 29347, 29363, 29383, 29387, 29389, 29399, 29401, 29411, 29423, 29429, 29437, + 29443, 29453, 29473, 29483, 29501, 29527, 29531, 29537, 29567, 29569, 29573, 29581, 29587, + 29599, 29611, 29629, 29633, 29641, 29663, 29669, 29671, 29683, 29717, 29723, 29741, 29753, + 29759, 29761, 29789, 29803, 29819, 29833, 29837, 29851, 29863, 29867, 29873, 29879, 29881, + 29917, 29921, 29927, 29947, 29959, 29983, 29989, 30011, 30013, 30029, 30047, 30059, 30071, + 30089, 30091, 30097, 30103, 30109, 30113, 30119, 30133, 30137, 30139, 30161, 30169, 30181, + 30187, 30197, 30203, 30211, 30223, 30241, 30253, 30259, 30269, 30271, 30293, 30307, 30313, + 30319, 30323, 30341, 30347, 30367, 30389, 30391, 30403, 30427, 30431, 30449, 30467, 30469, + 30491, 30493, 30497, 30509, 30517, 30529, 30539, 30553, 30557, 30559, 30577, 30593, 30631, + 30637, 30643, 30649, 30661, 30671, 30677, 30689, 30697, 30703, 30707, 30713, 30727, 30757, + 30763, 30773, 30781, 30803, 30809, 30817, 30829, 30839, 30841, 30851, 30853, 30859, 30869, + 30871, 30881, 30893, 30911, 30931, 30937, 30941, 30949, 30971, 30977, 30983, 31013, 31019, + 31033, 31039, 31051, 31063, 31069, 31079, 31081, 31091, 31121, 31123, 31139, 31147, 31151, + 31153, 31159, 31177, 31181, 31183, 31189, 31193, 31219, 31223, 31231, 31237, 31247, 31249, + 31253, 31259, 31267, 31271, 31277, 31307, 31319, 31321, 31327, 31333, 31337, 31357, 31379, + 31387, 31391, 31393, 31397, 31469, 31477, 31481, 31489, 31511, 31513, 31517, 31531, 31541, + 31543, 31547, 31567, 31573, 31583, 31601, 31607, 31627, 31643, 31649, 31657, 31663, 31667, + 31687, 31699, 31721, 31723, 31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817, + 31847, 31849, 31859, 31873, 31883, 31891, 31907, 31957, 31963, 31973, 31981, 31991, 32003, + 32009, 32027, 32029, 32051, 32057, 32059, 32063, 32069, 32077, 32083, 32089, 32099, 32117, + 32119, 32141, 32143, 32159, 32173, 32183, 32189, 32191, 32203, 32213, 32233, 32237, 32251, + 32257, 32261, 32297, 32299, 32303, 32309, 32321, 32323, 32327, 32341, 32353, 32359, 32363, + 32369, 32371, 32377, 32381, 32401, 32411, 32413, 32423, 32429, 32441, 32443, 32467, 32479, + 32491, 32497, 32503, 32507, 32531, 32533, 32537, 32561, 32563, 32569, 32573, 32579, 32587, + 32603, 32609, 32611, 32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717, 32719, + 32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803, 32831, 32833, 32839, 32843, 32869, + 32887, 32909, 32911, 32917, 32933, 32939, 32941, 32957, 32969, 32971, 32983, 32987, 32993, + 32999, 33013, 33023, 33029, 33037, 33049, 33053, 33071, 33073, 33083, 33091, 33107, 33113, + 33119, 33149, 33151, 33161, 33179, 33181, 33191, 33199, 33203, 33211, 33223, 33247, 33287, + 33289, 33301, 33311, 33317, 33329, 33331, 33343, 33347, 33349, 33353, 33359, 33377, 33391, + 33403, 33409, 33413, 33427, 33457, 33461, 33469, 33479, 33487, 33493, 33503, 33521, 33529, + 33533, 33547, 33563, 33569, 33577, 33581, 33587, 33589, 33599, 33601, 33613, 33617, 33619, + 33623, 33629, 33637, 33641, 33647, 33679, 33703, 33713, 33721, 33739, 33749, 33751, 33757, + 33767, 33769, 33773, 33791, 33797, 33809, 33811, 33827, 33829, 33851, 33857, 33863, 33871, + 33889, 33893, 33911, 33923, 33931, 33937, 33941, 33961, 33967, 33997, 34019, 34031, 34033, + 34039, 34057, 34061, 34123, 34127, 34129, 34141, 34147, 34157, 34159, 34171, 34183, 34211, + 34213, 34217, 34231, 34253, 34259, 34261, 34267, 34273, 34283, 34297, 34301, 34303, 34313, + 34319, 34327, 34337, 34351, 34361, 34367, 34369, 34381, 34403, 34421, 34429, 34439, 34457, + 34469, 34471, 34483, 34487, 34499, 34501, 34511, 34513, 34519, 34537, 34543, 34549, 34583, + 34589, 34591, 34603, 34607, 34613, 34631, 34649, 34651, 34667, 34673, 34679, 34687, 34693, + 34703, 34721, 34729, 34739, 34747, 34757, 34759, 34763, 34781, 34807, 34819, 34841, 34843, + 34847, 34849, 34871, 34877, 34883, 34897, 34913, 34919, 34939, 34949, 34961, 34963, 34981, + 35023, 35027, 35051, 35053, 35059, 35069, 35081, 35083, 35089, 35099, 35107, 35111, 35117, + 35129, 35141, 35149, 35153, 35159, 35171, 35201, 35221, 35227, 35251, 35257, 35267, 35279, + 35281, 35291, 35311, 35317, 35323, 35327, 35339, 35353, 35363, 35381, 35393, 35401, 35407, + 35419, 35423, 35437, 35447, 35449, 35461, 35491, 35507, 35509, 35521, 35527, 35531, 35533, + 35537, 35543, 35569, 35573, 35591, 35593, 35597, 35603, 35617, 35671, 35677, 35729, 35731, + 35747, 35753, 35759, 35771, 35797, 35801, 35803, 35809, 35831, 35837, 35839, 35851, 35863, + 35869, 35879, 35897, 35899, 35911, 35923, 35933, 35951, 35963, 35969, 35977, 35983, 35993, + 35999, 36007, 36011, 36013, 36017, 36037, 36061, 36067, 36073, 36083, 36097, 36107, 36109, + 36131, 36137, 36151, 36161, 36187, 36191, 36209, 36217, 36229, 36241, 36251, 36263, 36269, + 36277, 36293, 36299, 36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383, 36389, 36433, + 36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497, 36523, 36527, 36529, 36541, 36551, + 36559, 36563, 36571, 36583, 36587, 36599, 36607, 36629, 36637, 36643, 36653, 36671, 36677, + 36683, 36691, 36697, 36709, 36713, 36721, 36739, 36749, 36761, 36767, 36779, 36781, 36787, + 36791, 36793, 36809, 36821, 36833, 36847, 36857, 36871, 36877, 36887, 36899, 36901, 36913, + 36919, 36923, 36929, 36931, 36943, 36947, 36973, 36979, 36997, 37003, 37013, 37019, 37021, + 37039, 37049, 37057, 37061, 37087, 37097, 37117, 37123, 37139, 37159, 37171, 37181, 37189, + 37199, 37201, 37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309, 37313, 37321, 37337, + 37339, 37357, 37361, 37363, 37369, 37379, 37397, 37409, 37423, 37441, 37447, 37463, 37483, + 37489, 37493, 37501, 37507, 37511, 37517, 37529, 37537, 37547, 37549, 37561, 37567, 37571, + 37573, 37579, 37589, 37591, 37607, 37619, 37633, 37643, 37649, 37657, 37663, 37691, 37693, + 37699, 37717, 37747, 37781, 37783, 37799, 37811, 37813, 37831, 37847, 37853, 37861, 37871, + 37879, 37889, 37897, 37907, 37951, 37957, 37963, 37967, 37987, 37991, 37993, 37997, 38011, + 38039, 38047, 38053, 38069, 38083, 38113, 38119, 38149, 38153, 38167, 38177, 38183, 38189, + 38197, 38201, 38219, 38231, 38237, 38239, 38261, 38273, 38281, 38287, 38299, 38303, 38317, + 38321, 38327, 38329, 38333, 38351, 38371, 38377, 38393, 38431, 38447, 38449, 38453, 38459, + 38461, 38501, 38543, 38557, 38561, 38567, 38569, 38593, 38603, 38609, 38611, 38629, 38639, + 38651, 38653, 38669, 38671, 38677, 38693, 38699, 38707, 38711, 38713, 38723, 38729, 38737, + 38747, 38749, 38767, 38783, 38791, 38803, 38821, 38833, 38839, 38851, 38861, 38867, 38873, + 38891, 38903, 38917, 38921, 38923, 38933, 38953, 38959, 38971, 38977, 38993, 39019, 39023, + 39041, 39043, 39047, 39079, 39089, 39097, 39103, 39107, 39113, 39119, 39133, 39139, 39157, + 39161, 39163, 39181, 39191, 39199, 39209, 39217, 39227, 39229, 39233, 39239, 39241, 39251, + 39293, 39301, 39313, 39317, 39323, 39341, 39343, 39359, 39367, 39371, 39373, 39383, 39397, + 39409, 39419, 39439, 39443, 39451, 39461, 39499, 39503, 39509, 39511, 39521, 39541, 39551, + 39563, 39569, 39581, 39607, 39619, 39623, 39631, 39659, 39667, 39671, 39679, 39703, 39709, + 39719, 39727, 39733, 39749, 39761, 39769, 39779, 39791, 39799, 39821, 39827, 39829, 39839, + 39841, 39847, 39857, 39863, 39869, 39877, 39883, 39887, 39901, 39929, 39937, 39953, 39971, + 39979, 39983, 39989, 40009, 40013, 40031, 40037, 40039, 40063, 40087, 40093, 40099, 40111, + 40123, 40127, 40129, 40151, 40153, 40163, 40169, 40177, 40189, 40193, 40213, 40231, 40237, + 40241, 40253, 40277, 40283, 40289, 40343, 40351, 40357, 40361, 40387, 40423, 40427, 40429, + 40433, 40459, 40471, 40483, 40487, 40493, 40499, 40507, 40519, 40529, 40531, 40543, 40559, + 40577, 40583, 40591, 40597, 40609, 40627, 40637, 40639, 40693, 40697, 40699, 40709, 40739, + 40751, 40759, 40763, 40771, 40787, 40801, 40813, 40819, 40823, 40829, 40841, 40847, 40849, + 40853, 40867, 40879, 40883, 40897, 40903, 40927, 40933, 40939, 40949, 40961, 40973, 40993, + 41011, 41017, 41023, 41039, 41047, 41051, 41057, 41077, 41081, 41113, 41117, 41131, 41141, + 41143, 41149, 41161, 41177, 41179, 41183, 41189, 41201, 41203, 41213, 41221, 41227, 41231, + 41233, 41243, 41257, 41263, 41269, 41281, 41299, 41333, 41341, 41351, 41357, 41381, 41387, + 41389, 41399, 41411, 41413, 41443, 41453, 41467, 41479, 41491, 41507, 41513, 41519, 41521, + 41539, 41543, 41549, 41579, 41593, 41597, 41603, 41609, 41611, 41617, 41621, 41627, 41641, + 41647, 41651, 41659, 41669, 41681, 41687, 41719, 41729, 41737, 41759, 41761, 41771, 41777, + 41801, 41809, 41813, 41843, 41849, 41851, 41863, 41879, 41887, 41893, 41897, 41903, 41911, + 41927, 41941, 41947, 41953, 41957, 41959, 41969, 41981, 41983, 41999, 42013, 42017, 42019, + 42023, 42043, 42061, 42071, 42073, 42083, 42089, 42101, 42131, 42139, 42157, 42169, 42179, + 42181, 42187, 42193, 42197, 42209, 42221, 42223, 42227, 42239, 42257, 42281, 42283, 42293, + 42299, 42307, 42323, 42331, 42337, 42349, 42359, 42373, 42379, 42391, 42397, 42403, 42407, + 42409, 42433, 42437, 42443, 42451, 42457, 42461, 42463, 42467, 42473, 42487, 42491, 42499, + 42509, 42533, 42557, 42569, 42571, 42577, 42589, 42611, 42641, 42643, 42649, 42667, 42677, + 42683, 42689, 42697, 42701, 42703, 42709, 42719, 42727, 42737, 42743, 42751, 42767, 42773, + 42787, 42793, 42797, 42821, 42829, 42839, 42841, 42853, 42859, 42863, 42899, 42901, 42923, + 42929, 42937, 42943, 42953, 42961, 42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, + 43051, 43063, 43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177, 43189, 43201, 43207, + 43223, 43237, 43261, 43271, 43283, 43291, 43313, 43319, 43321, 43331, 43391, 43397, 43399, + 43403, 43411, 43427, 43441, 43451, 43457, 43481, 43487, 43499, 43517, 43541, 43543, 43573, + 43577, 43579, 43591, 43597, 43607, 43609, 43613, 43627, 43633, 43649, 43651, 43661, 43669, + 43691, 43711, 43717, 43721, 43753, 43759, 43777, 43781, 43783, 43787, 43789, 43793, 43801, + 43853, 43867, 43889, 43891, 43913, 43933, 43943, 43951, 43961, 43963, 43969, 43973, 43987, + 43991, 43997, 44017, 44021, 44027, 44029, 44041, 44053, 44059, 44071, 44087, 44089, 44101, + 44111, 44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189, 44201, 44203, 44207, 44221, + 44249, 44257, 44263, 44267, 44269, 44273, 44279, 44281, 44293, 44351, 44357, 44371, 44381, + 44383, 44389, 44417, 44449, 44453, 44483, 44491, 44497, 44501, 44507, 44519, 44531, 44533, + 44537, 44543, 44549, 44563, 44579, 44587, 44617, 44621, 44623, 44633, 44641, 44647, 44651, + 44657, 44683, 44687, 44699, 44701, 44711, 44729, 44741, 44753, 44771, 44773, 44777, 44789, + 44797, 44809, 44819, 44839, 44843, 44851, 44867, 44879, 44887, 44893, 44909, 44917, 44927, + 44939, 44953, 44959, 44963, 44971, 44983, 44987, 45007, 45013, 45053, 45061, 45077, 45083, + 45119, 45121, 45127, 45131, 45137, 45139, 45161, 45179, 45181, 45191, 45197, 45233, 45247, + 45259, 45263, 45281, 45289, 45293, 45307, 45317, 45319, 45329, 45337, 45341, 45343, 45361, + 45377, 45389, 45403, 45413, 45427, 45433, 45439, 45481, 45491, 45497, 45503, 45523, 45533, + 45541, 45553, 45557, 45569, 45587, 45589, 45599, 45613, 45631, 45641, 45659, 45667, 45673, + 45677, 45691, 45697, 45707, 45737, 45751, 45757, 45763, 45767, 45779, 45817, 45821, 45823, + 45827, 45833, 45841, 45853, 45863, 45869, 45887, 45893, 45943, 45949, 45953, 45959, 45971, + 45979, 45989, 46021, 46027, 46049, 46051, 46061, 46073, 46091, 46093, 46099, 46103, 46133, + 46141, 46147, 46153, 46171, 46181, 46183, 46187, 46199, 46219, 46229, 46237, 46261, 46271, + 46273, 46279, 46301, 46307, 46309, 46327, 46337, 46349, 46351, 46381, 46399, 46411, 46439, + 46441, 46447, 46451, 46457, 46471, 46477, 46489, 46499, 46507, 46511, 46523, 46549, 46559, + 46567, 46573, 46589, 46591, 46601, 46619, 46633, 46639, 46643, 46649, 46663, 46679, 46681, + 46687, 46691, 46703, 46723, 46727, 46747, 46751, 46757, 46769, 46771, 46807, 46811, 46817, + 46819, 46829, 46831, 46853, 46861, 46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993, + 46997, 47017, 47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119, 47123, 47129, 47137, + 47143, 47147, 47149, 47161, 47189, 47207, 47221, 47237, 47251, 47269, 47279, 47287, 47293, + 47297, 47303, 47309, 47317, 47339, 47351, 47353, 47363, 47381, 47387, 47389, 47407, 47417, + 47419, 47431, 47441, 47459, 47491, 47497, 47501, 47507, 47513, 47521, 47527, 47533, 47543, + 47563, 47569, 47581, 47591, 47599, 47609, 47623, 47629, 47639, 47653, 47657, 47659, 47681, + 47699, 47701, 47711, 47713, 47717, 47737, 47741, 47743, 47777, 47779, 47791, 47797, 47807, + 47809, 47819, 47837, 47843, 47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939, 47947, + 47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049, 48073, 48079, 48091, 48109, + 48119, 48121, 48131, 48157, 48163, 48179, 48187, 48193, 48197, 48221, 48239, 48247, 48259, + 48271, 48281, 48299, 48311, 48313, 48337, 48341, 48353, 48371, 48383, 48397, 48407, 48409, + 48413, 48437, 48449, 48463, 48473, 48479, 48481, 48487, 48491, 48497, 48523, 48527, 48533, + 48539, 48541, 48563, 48571, 48589, 48593, 48611, 48619, 48623, 48647, 48649, 48661, 48673, + 48677, 48679, 48731, 48733, 48751, 48757, 48761, 48767, 48779, 48781, 48787, 48799, 48809, + 48817, 48821, 48823, 48847, 48857, 48859, 48869, 48871, 48883, 48889, 48907, 48947, 48953, + 48973, 48989, 48991, 49003, 49009, 49019, 49031, 49033, 49037, 49043, 49057, 49069, 49081, + 49103, 49109, 49117, 49121, 49123, 49139, 49157, 49169, 49171, 49177, 49193, 49199, 49201, + 49207, 49211, 49223, 49253, 49261, 49277, 49279, 49297, 49307, 49331, 49333, 49339, 49363, + 49367, 49369, 49391, 49393, 49409, 49411, 49417, 49429, 49433, 49451, 49459, 49463, 49477, + 49481, 49499, 49523, 49529, 49531, 49537, 49547, 49549, 49559, 49597, 49603, 49613, 49627, + 49633, 49639, 49663, 49667, 49669, 49681, 49697, 49711, 49727, 49739, 49741, 49747, 49757, + 49783, 49787, 49789, 49801, 49807, 49811, 49823, 49831, 49843, 49853, 49871, 49877, 49891, + 49919, 49921, 49927, 49937, 49939, 49943, 49957, 49991, 49993, 49999, 50021, 50023, 50033, + 50047, 50051, 50053, 50069, 50077, 50087, 50093, 50101, 50111, 50119, 50123, 50129, 50131, + 50147, 50153, 50159, 50177, 50207, 50221, 50227, 50231, 50261, 50263, 50273, 50287, 50291, + 50311, 50321, 50329, 50333, 50341, 50359, 50363, 50377, 50383, 50387, 50411, 50417, 50423, + 50441, 50459, 50461, 50497, 50503, 50513, 50527, 50539, 50543, 50549, 50551, 50581, 50587, + 50591, 50593, 50599, 50627, 50647, 50651, 50671, 50683, 50707, 50723, 50741, 50753, 50767, + 50773, 50777, 50789, 50821, 50833, 50839, 50849, 50857, 50867, 50873, 50891, 50893, 50909, + 50923, 50929, 50951, 50957, 50969, 50971, 50989, 50993, 51001, 51031, 51043, 51047, 51059, + 51061, 51071, 51109, 51131, 51133, 51137, 51151, 51157, 51169, 51193, 51197, 51199, 51203, + 51217, 51229, 51239, 51241, 51257, 51263, 51283, 51287, 51307, 51329, 51341, 51343, 51347, + 51349, 51361, 51383, 51407, 51413, 51419, 51421, 51427, 51431, 51437, 51439, 51449, 51461, + 51473, 51479, 51481, 51487, 51503, 51511, 51517, 51521, 51539, 51551, 51563, 51577, 51581, + 51593, 51599, 51607, 51613, 51631, 51637, 51647, 51659, 51673, 51679, 51683, 51691, 51713, + 51719, 51721, 51749, 51767, 51769, 51787, 51797, 51803, 51817, 51827, 51829, 51839, 51853, + 51859, 51869, 51871, 51893, 51899, 51907, 51913, 51929, 51941, 51949, 51971, 51973, 51977, + 51991, 52009, 52021, 52027, 52051, 52057, 52067, 52069, 52081, 52103, 52121, 52127, 52147, + 52153, 52163, 52177, 52181, 52183, 52189, 52201, 52223, 52237, 52249, 52253, 52259, 52267, + 52289, 52291, 52301, 52313, 52321, 52361, 52363, 52369, 52379, 52387, 52391, 52433, 52453, + 52457, 52489, 52501, 52511, 52517, 52529, 52541, 52543, 52553, 52561, 52567, 52571, 52579, + 52583, 52609, 52627, 52631, 52639, 52667, 52673, 52691, 52697, 52709, 52711, 52721, 52727, + 52733, 52747, 52757, 52769, 52783, 52807, 52813, 52817, 52837, 52859, 52861, 52879, 52883, + 52889, 52901, 52903, 52919, 52937, 52951, 52957, 52963, 52967, 52973, 52981, 52999, 53003, + 53017, 53047, 53051, 53069, 53077, 53087, 53089, 53093, 53101, 53113, 53117, 53129, 53147, + 53149, 53161, 53171, 53173, 53189, 53197, 53201, 53231, 53233, 53239, 53267, 53269, 53279, + 53281, 53299, 53309, 53323, 53327, 53353, 53359, 53377, 53381, 53401, 53407, 53411, 53419, + 53437, 53441, 53453, 53479, 53503, 53507, 53527, 53549, 53551, 53569, 53591, 53593, 53597, + 53609, 53611, 53617, 53623, 53629, 53633, 53639, 53653, 53657, 53681, 53693, 53699, 53717, + 53719, 53731, 53759, 53773, 53777, 53783, 53791, 53813, 53819, 53831, 53849, 53857, 53861, + 53881, 53887, 53891, 53897, 53899, 53917, 53923, 53927, 53939, 53951, 53959, 53987, 53993, + 54001, 54011, 54013, 54037, 54049, 54059, 54083, 54091, 54101, 54121, 54133, 54139, 54151, + 54163, 54167, 54181, 54193, 54217, 54251, 54269, 54277, 54287, 54293, 54311, 54319, 54323, + 54331, 54347, 54361, 54367, 54371, 54377, 54401, 54403, 54409, 54413, 54419, 54421, 54437, + 54443, 54449, 54469, 54493, 54497, 54499, 54503, 54517, 54521, 54539, 54541, 54547, 54559, + 54563, 54577, 54581, 54583, 54601, 54617, 54623, 54629, 54631, 54647, 54667, 54673, 54679, + 54709, 54713, 54721, 54727, 54751, 54767, 54773, 54779, 54787, 54799, 54829, 54833, 54851, + 54869, 54877, 54881, 54907, 54917, 54919, 54941, 54949, 54959, 54973, 54979, 54983, 55001, + 55009, 55021, 55049, 55051, 55057, 55061, 55073, 55079, 55103, 55109, 55117, 55127, 55147, + 55163, 55171, 55201, 55207, 55213, 55217, 55219, 55229, 55243, 55249, 55259, 55291, 55313, + 55331, 55333, 55337, 55339, 55343, 55351, 55373, 55381, 55399, 55411, 55439, 55441, 55457, + 55469, 55487, 55501, 55511, 55529, 55541, 55547, 55579, 55589, 55603, 55609, 55619, 55621, + 55631, 55633, 55639, 55661, 55663, 55667, 55673, 55681, 55691, 55697, 55711, 55717, 55721, + 55733, 55763, 55787, 55793, 55799, 55807, 55813, 55817, 55819, 55823, 55829, 55837, 55843, + 55849, 55871, 55889, 55897, 55901, 55903, 55921, 55927, 55931, 55933, 55949, 55967, 55987, + 55997, 56003, 56009, 56039, 56041, 56053, 56081, 56087, 56093, 56099, 56101, 56113, 56123, + 56131, 56149, 56167, 56171, 56179, 56197, 56207, 56209, 56237, 56239, 56249, 56263, 56267, + 56269, 56299, 56311, 56333, 56359, 56369, 56377, 56383, 56393, 56401, 56417, 56431, 56437, + 56443, 56453, 56467, 56473, 56477, 56479, 56489, 56501, 56503, 56509, 56519, 56527, 56531, + 56533, 56543, 56569, 56591, 56597, 56599, 56611, 56629, 56633, 56659, 56663, 56671, 56681, + 56687, 56701, 56711, 56713, 56731, 56737, 56747, 56767, 56773, 56779, 56783, 56807, 56809, + 56813, 56821, 56827, 56843, 56857, 56873, 56891, 56893, 56897, 56909, 56911, 56921, 56923, + 56929, 56941, 56951, 56957, 56963, 56983, 56989, 56993, 56999, 57037, 57041, 57047, 57059, + 57073, 57077, 57089, 57097, 57107, 57119, 57131, 57139, 57143, 57149, 57163, 57173, 57179, + 57191, 57193, 57203, 57221, 57223, 57241, 57251, 57259, 57269, 57271, 57283, 57287, 57301, + 57329, 57331, 57347, 57349, 57367, 57373, 57383, 57389, 57397, 57413, 57427, 57457, 57467, + 57487, 57493, 57503, 57527, 57529, 57557, 57559, 57571, 57587, 57593, 57601, 57637, 57641, + 57649, 57653, 57667, 57679, 57689, 57697, 57709, 57713, 57719, 57727, 57731, 57737, 57751, + 57773, 57781, 57787, 57791, 57793, 57803, 57809, 57829, 57839, 57847, 57853, 57859, 57881, + 57899, 57901, 57917, 57923, 57943, 57947, 57973, 57977, 57991, 58013, 58027, 58031, 58043, + 58049, 58057, 58061, 58067, 58073, 58099, 58109, 58111, 58129, 58147, 58151, 58153, 58169, + 58171, 58189, 58193, 58199, 58207, 58211, 58217, 58229, 58231, 58237, 58243, 58271, 58309, + 58313, 58321, 58337, 58363, 58367, 58369, 58379, 58391, 58393, 58403, 58411, 58417, 58427, + 58439, 58441, 58451, 58453, 58477, 58481, 58511, 58537, 58543, 58549, 58567, 58573, 58579, + 58601, 58603, 58613, 58631, 58657, 58661, 58679, 58687, 58693, 58699, 58711, 58727, 58733, + 58741, 58757, 58763, 58771, 58787, 58789, 58831, 58889, 58897, 58901, 58907, 58909, 58913, + 58921, 58937, 58943, 58963, 58967, 58979, 58991, 58997, 59009, 59011, 59021, 59023, 59029, + 59051, 59053, 59063, 59069, 59077, 59083, 59093, 59107, 59113, 59119, 59123, 59141, 59149, + 59159, 59167, 59183, 59197, 59207, 59209, 59219, 59221, 59233, 59239, 59243, 59263, 59273, + 59281, 59333, 59341, 59351, 59357, 59359, 59369, 59377, 59387, 59393, 59399, 59407, 59417, + 59419, 59441, 59443, 59447, 59453, 59467, 59471, 59473, 59497, 59509, 59513, 59539, 59557, + 59561, 59567, 59581, 59611, 59617, 59621, 59627, 59629, 59651, 59659, 59663, 59669, 59671, + 59693, 59699, 59707, 59723, 59729, 59743, 59747, 59753, 59771, 59779, 59791, 59797, 59809, + 59833, 59863, 59879, 59887, 59921, 59929, 59951, 59957, 59971, 59981, 59999, 60013, 60017, + 60029, 60037, 60041, 60077, 60083, 60089, 60091, 60101, 60103, 60107, 60127, 60133, 60139, + 60149, 60161, 60167, 60169, 60209, 60217, 60223, 60251, 60257, 60259, 60271, 60289, 60293, + 60317, 60331, 60337, 60343, 60353, 60373, 60383, 60397, 60413, 60427, 60443, 60449, 60457, + 60493, 60497, 60509, 60521, 60527, 60539, 60589, 60601, 60607, 60611, 60617, 60623, 60631, + 60637, 60647, 60649, 60659, 60661, 60679, 60689, 60703, 60719, 60727, 60733, 60737, 60757, + 60761, 60763, 60773, 60779, 60793, 60811, 60821, 60859, 60869, 60887, 60889, 60899, 60901, + 60913, 60917, 60919, 60923, 60937, 60943, 60953, 60961, 61001, 61007, 61027, 61031, 61043, + 61051, 61057, 61091, 61099, 61121, 61129, 61141, 61151, 61153, 61169, 61211, 61223, 61231, + 61253, 61261, 61283, 61291, 61297, 61331, 61333, 61339, 61343, 61357, 61363, 61379, 61381, + 61403, 61409, 61417, 61441, 61463, 61469, 61471, 61483, 61487, 61493, 61507, 61511, 61519, + 61543, 61547, 61553, 61559, 61561, 61583, 61603, 61609, 61613, 61627, 61631, 61637, 61643, + 61651, 61657, 61667, 61673, 61681, 61687, 61703, 61717, 61723, 61729, 61751, 61757, 61781, + 61813, 61819, 61837, 61843, 61861, 61871, 61879, 61909, 61927, 61933, 61949, 61961, 61967, + 61979, 61981, 61987, 61991, 62003, 62011, 62017, 62039, 62047, 62053, 62057, 62071, 62081, + 62099, 62119, 62129, 62131, 62137, 62141, 62143, 62171, 62189, 62191, 62201, 62207, 62213, + 62219, 62233, 62273, 62297, 62299, 62303, 62311, 62323, 62327, 62347, 62351, 62383, 62401, + 62417, 62423, 62459, 62467, 62473, 62477, 62483, 62497, 62501, 62507, 62533, 62539, 62549, + 62563, 62581, 62591, 62597, 62603, 62617, 62627, 62633, 62639, 62653, 62659, 62683, 62687, + 62701, 62723, 62731, 62743, 62753, 62761, 62773, 62791, 62801, 62819, 62827, 62851, 62861, + 62869, 62873, 62897, 62903, 62921, 62927, 62929, 62939, 62969, 62971, 62981, 62983, 62987, + 62989, 63029, 63031, 63059, 63067, 63073, 63079, 63097, 63103, 63113, 63127, 63131, 63149, + 63179, 63197, 63199, 63211, 63241, 63247, 63277, 63281, 63299, 63311, 63313, 63317, 63331, + 63337, 63347, 63353, 63361, 63367, 63377, 63389, 63391, 63397, 63409, 63419, 63421, 63439, + 63443, 63463, 63467, 63473, 63487, 63493, 63499, 63521, 63527, 63533, 63541, 63559, 63577, + 63587, 63589, 63599, 63601, 63607, 63611, 63617, 63629, 63647, 63649, 63659, 63667, 63671, + 63689, 63691, 63697, 63703, 63709, 63719, 63727, 63737, 63743, 63761, 63773, 63781, 63793, + 63799, 63803, 63809, 63823, 63839, 63841, 63853, 63857, 63863, 63901, 63907, 63913, 63929, + 63949, 63977, 63997, 64007, 64013, 64019, 64033, 64037, 64063, 64067, 64081, 64091, 64109, + 64123, 64151, 64153, 64157, 64171, 64187, 64189, 64217, 64223, 64231, 64237, 64271, 64279, + 64283, 64301, 64303, 64319, 64327, 64333, 64373, 64381, 64399, 64403, 64433, 64439, 64451, + 64453, 64483, 64489, 64499, 64513, 64553, 64567, 64577, 64579, 64591, 64601, 64609, 64613, + 64621, 64627, 64633, 64661, 64663, 64667, 64679, 64693, 64709, 64717, 64747, 64763, 64781, + 64783, 64793, 64811, 64817, 64849, 64853, 64871, 64877, 64879, 64891, 64901, 64919, 64921, + 64927, 64937, 64951, 64969, 64997, 65003, 65011, 65027, 65029, 65033, 65053, 65063, 65071, + 65089, 65099, 65101, 65111, 65119, 65123, 65129, 65141, 65147, 65167, 65171, 65173, 65179, + 65183, 65203, 65213, 65239, 65257, 65267, 65269, 65287, 65293, 65309, 65323, 65327, 65353, + 65357, 65371, 65381, 65393, 65407, 65413, 65419, 65423, 65437, 65447, 65449, 65479, 65497, + 65519, 65521, 0}; } /* -* Modular Reducer -* (C) 1999-2011,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Modular Reducer + * (C) 1999-2011,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Modular_Reducer Constructor -*/ -Modular_Reducer::Modular_Reducer(const BigInt& mod) - { - if(mod < 0) - throw Invalid_Argument("Modular_Reducer: modulus must be positive"); + * Modular_Reducer Constructor + */ +Modular_Reducer::Modular_Reducer(const BigInt& mod) { + if (mod < 0) throw Invalid_Argument("Modular_Reducer: modulus must be positive"); - // Left uninitialized if mod == 0 - m_mod_words = 0; + // Left uninitialized if mod == 0 + m_mod_words = 0; - if(mod > 0) - { - m_modulus = mod; - m_mod_words = m_modulus.sig_words(); + if (mod > 0) { + m_modulus = mod; + m_mod_words = m_modulus.sig_words(); - // Compute mu = floor(2^{2k} / m) - m_mu.set_bit(2 * BOTAN_MP_WORD_BITS * m_mod_words); - m_mu = ct_divide(m_mu, m_modulus); - } - } + // Compute mu = floor(2^{2k} / m) + m_mu.set_bit(2 * BOTAN_MP_WORD_BITS * m_mod_words); + m_mu = ct_divide(m_mu, m_modulus); + } +} -BigInt Modular_Reducer::reduce(const BigInt& x) const - { - BigInt r; - secure_vector ws; - reduce(r, x, ws); - return r; - } +BigInt Modular_Reducer::reduce(const BigInt& x) const { + BigInt r; + secure_vector ws; + reduce(r, x, ws); + return r; +} namespace { /* -* Like if(cnd) x.rev_sub(...) but in const time -*/ -void cnd_rev_sub(bool cnd, BigInt& x, const word y[], size_t y_sw, secure_vector& ws) - { - if(x.sign() != BigInt::Positive) - throw Invalid_State("BigInt::sub_rev requires this is positive"); + * Like if(cnd) x.rev_sub(...) but in const time + */ +void cnd_rev_sub(bool cnd, BigInt& x, const word y[], size_t y_sw, secure_vector& ws) { + if (x.sign() != BigInt::Positive) + throw Invalid_State("BigInt::sub_rev requires this is positive"); - const size_t x_sw = x.sig_words(); + const size_t x_sw = x.sig_words(); - const size_t max_words = std::max(x_sw, y_sw); - ws.resize(std::max(x_sw, y_sw)); - clear_mem(ws.data(), ws.size()); - x.grow_to(max_words); + const size_t max_words = std::max(x_sw, y_sw); + ws.resize(std::max(x_sw, y_sw)); + clear_mem(ws.data(), ws.size()); + x.grow_to(max_words); - const int32_t relative_size = bigint_sub_abs(ws.data(), x.data(), x_sw, y, y_sw); - - x.cond_flip_sign((relative_size > 0) && cnd); - bigint_cnd_swap(cnd, x.mutable_data(), ws.data(), max_words); - } + const int32_t relative_size = bigint_sub_abs(ws.data(), x.data(), x_sw, y, y_sw); + x.cond_flip_sign((relative_size > 0) && cnd); + bigint_cnd_swap(cnd, x.mutable_data(), ws.data(), max_words); } -void Modular_Reducer::reduce(BigInt& t1, const BigInt& x, secure_vector& ws) const - { - if(&t1 == &x) - throw Invalid_State("Modular_Reducer arguments cannot alias"); - if(m_mod_words == 0) - throw Invalid_State("Modular_Reducer: Never initalized"); +} // namespace - const size_t x_sw = x.sig_words(); +void Modular_Reducer::reduce(BigInt& t1, const BigInt& x, secure_vector& ws) const { + if (&t1 == &x) throw Invalid_State("Modular_Reducer arguments cannot alias"); + if (m_mod_words == 0) throw Invalid_State("Modular_Reducer: Never initalized"); - if(x_sw > 2*m_mod_words) - { - // too big, fall back to slow boat division - t1 = ct_modulo(x, m_modulus); - return; - } + const size_t x_sw = x.sig_words(); - t1 = x; - t1.set_sign(BigInt::Positive); - t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words - 1)); + if (x_sw > 2 * m_mod_words) { + // too big, fall back to slow boat division + t1 = ct_modulo(x, m_modulus); + return; + } - t1.mul(m_mu, ws); - t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words + 1)); + t1 = x; + t1.set_sign(BigInt::Positive); + t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words - 1)); - // TODO add masked mul to avoid computing high bits - t1.mul(m_modulus, ws); - t1.mask_bits(BOTAN_MP_WORD_BITS * (m_mod_words + 1)); + t1.mul(m_mu, ws); + t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words + 1)); - t1.rev_sub(x.data(), std::min(x_sw, m_mod_words + 1), ws); + // TODO add masked mul to avoid computing high bits + t1.mul(m_modulus, ws); + t1.mask_bits(BOTAN_MP_WORD_BITS * (m_mod_words + 1)); - /* - * If t1 < 0 then we must add b^(k+1) where b = 2^w. To avoid a - * side channel perform the addition unconditionally, with ws set - * to either b^(k+1) or else 0. - */ - const word t1_neg = t1.is_negative(); + t1.rev_sub(x.data(), std::min(x_sw, m_mod_words + 1), ws); - if(ws.size() < m_mod_words + 2) - ws.resize(m_mod_words + 2); - clear_mem(ws.data(), ws.size()); - ws[m_mod_words + 1] = t1_neg; + /* + * If t1 < 0 then we must add b^(k+1) where b = 2^w. To avoid a + * side channel perform the addition unconditionally, with ws set + * to either b^(k+1) or else 0. + */ + const word t1_neg = t1.is_negative(); - t1.add(ws.data(), m_mod_words + 2, BigInt::Positive); + if (ws.size() < m_mod_words + 2) ws.resize(m_mod_words + 2); + clear_mem(ws.data(), ws.size()); + ws[m_mod_words + 1] = t1_neg; - // Per HAC this step requires at most 2 subtractions - t1.ct_reduce_below(m_modulus, ws, 2); + t1.add(ws.data(), m_mod_words + 2, BigInt::Positive); - cnd_rev_sub(t1.is_nonzero() && x.is_negative(), t1, m_modulus.data(), m_modulus.size(), ws); - } + // Per HAC this step requires at most 2 subtractions + t1.ct_reduce_below(m_modulus, ws, 2); + cnd_rev_sub(t1.is_nonzero() && x.is_negative(), t1, m_modulus.data(), m_modulus.size(), ws); } + +} // namespace Botan /* -* Shanks-Tonnelli (RESSOL) -* (C) 2007-2008 Falko Strenzke, FlexSecure GmbH -* (C) 2008 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Shanks-Tonnelli (RESSOL) + * (C) 2007-2008 Falko Strenzke, FlexSecure GmbH + * (C) 2008 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { /* -* Shanks-Tonnelli algorithm -*/ -BigInt ressol(const BigInt& a, const BigInt& p) - { - if(a == 0) - return 0; - else if(a < 0) - throw Invalid_Argument("ressol: value to solve for must be positive"); - else if(a >= p) - throw Invalid_Argument("ressol: value to solve for must be less than p"); + * Shanks-Tonnelli algorithm + */ +BigInt ressol(const BigInt& a, const BigInt& p) { + if (a == 0) + return 0; + else if (a < 0) + throw Invalid_Argument("ressol: value to solve for must be positive"); + else if (a >= p) + throw Invalid_Argument("ressol: value to solve for must be less than p"); - if(p == 2) - return a; - else if(p <= 1) - throw Invalid_Argument("ressol: prime must be > 1 a"); - else if(p.is_even()) - throw Invalid_Argument("ressol: invalid prime"); + if (p == 2) + return a; + else if (p <= 1) + throw Invalid_Argument("ressol: prime must be > 1 a"); + else if (p.is_even()) + throw Invalid_Argument("ressol: invalid prime"); - if(jacobi(a, p) != 1) // not a quadratic residue - return -BigInt(1); + if (jacobi(a, p) != 1) // not a quadratic residue + return -BigInt(1); - if(p % 4 == 3) - return power_mod(a, ((p+1) >> 2), p); + if (p % 4 == 3) return power_mod(a, ((p + 1) >> 2), p); - size_t s = low_zero_bits(p - 1); - BigInt q = p >> s; + size_t s = low_zero_bits(p - 1); + BigInt q = p >> s; - q -= 1; - q >>= 1; + q -= 1; + q >>= 1; - Modular_Reducer mod_p(p); + Modular_Reducer mod_p(p); - BigInt r = power_mod(a, q, p); - BigInt n = mod_p.multiply(a, mod_p.square(r)); - r = mod_p.multiply(r, a); + BigInt r = power_mod(a, q, p); + BigInt n = mod_p.multiply(a, mod_p.square(r)); + r = mod_p.multiply(r, a); - if(n == 1) - return r; + if (n == 1) return r; - // find random non quadratic residue z - BigInt z = 2; - while(jacobi(z, p) == 1) // while z quadratic residue - ++z; + // find random non quadratic residue z + BigInt z = 2; + while (jacobi(z, p) == 1) // while z quadratic residue + ++z; - BigInt c = power_mod(z, (q << 1) + 1, p); + BigInt c = power_mod(z, (q << 1) + 1, p); - while(n > 1) - { - q = n; + while (n > 1) { + q = n; - size_t i = 0; - while(q != 1) - { - q = mod_p.square(q); - ++i; + size_t i = 0; + while (q != 1) { + q = mod_p.square(q); + ++i; - if(i >= s) - { - return -BigInt(1); + if (i >= s) { + return -BigInt(1); } - } + } - c = power_mod(c, BigInt::power_of_2(s-i-1), p); - r = mod_p.multiply(r, c); - c = mod_p.square(c); - n = mod_p.multiply(n, c); - s = i; - } - - return r; - } + c = power_mod(c, BigInt::power_of_2(s - i - 1), p); + r = mod_p.multiply(r, c); + c = mod_p.square(c); + n = mod_p.multiply(n, c); + s = i; + } + return r; } -/* -* PBKDF -* (C) 2012 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * PBKDF + * (C) 2012 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_PBKDF1) #endif @@ -20801,120 +18889,96 @@ BigInt ressol(const BigInt& a, const BigInt& p) namespace Botan { -std::unique_ptr PBKDF::create(const std::string& algo_spec, - const std::string& provider) - { - const SCAN_Name req(algo_spec); +std::unique_ptr PBKDF::create(const std::string& algo_spec, const std::string& provider) { + const SCAN_Name req(algo_spec); #if defined(BOTAN_HAS_PBKDF2) - if(req.algo_name() == "PBKDF2") - { - // TODO OpenSSL + if (req.algo_name() == "PBKDF2") { + // TODO OpenSSL - if(provider.empty() || provider == "base") - { - if(auto mac = MessageAuthenticationCode::create(req.arg(0))) - return std::unique_ptr(new PKCS5_PBKDF2(mac.release())); + if (provider.empty() || provider == "base") { + if (auto mac = MessageAuthenticationCode::create(req.arg(0))) + return std::unique_ptr(new PKCS5_PBKDF2(mac.release())); - if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) - return std::unique_ptr(new PKCS5_PBKDF2(mac.release())); - } + if (auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) + return std::unique_ptr(new PKCS5_PBKDF2(mac.release())); + } - return nullptr; - } + return nullptr; + } #endif #if defined(BOTAN_HAS_PBKDF1) - if(req.algo_name() == "PBKDF1" && req.arg_count() == 1) - { - if(auto hash = HashFunction::create(req.arg(0))) - return std::unique_ptr(new PKCS5_PBKDF1(hash.release())); - - } + if (req.algo_name() == "PBKDF1" && req.arg_count() == 1) { + if (auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new PKCS5_PBKDF1(hash.release())); + } #endif #if defined(BOTAN_HAS_PGP_S2K) - if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) - { - if(auto hash = HashFunction::create(req.arg(0))) - return std::unique_ptr(new OpenPGP_S2K(hash.release())); - } + if (req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) { + if (auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new OpenPGP_S2K(hash.release())); + } #endif - BOTAN_UNUSED(req); - BOTAN_UNUSED(provider); - - return nullptr; - } - -//static -std::unique_ptr -PBKDF::create_or_throw(const std::string& algo, - const std::string& provider) - { - if(auto pbkdf = PBKDF::create(algo, provider)) - { - return pbkdf; - } - throw Lookup_Error("PBKDF", algo, provider); - } - -std::vector PBKDF::providers(const std::string& algo_spec) - { - return probe_providers_of(algo_spec, { "base", "openssl" }); - } - -void PBKDF::pbkdf_timed(uint8_t out[], size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - std::chrono::milliseconds msec, - size_t& iterations) const - { - iterations = pbkdf(out, out_len, passphrase, salt, salt_len, 0, msec); - } - -void PBKDF::pbkdf_iterations(uint8_t out[], size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - size_t iterations) const - { - if(iterations == 0) - throw Invalid_Argument(name() + ": Invalid iteration count"); - - const size_t iterations_run = pbkdf(out, out_len, passphrase, - salt, salt_len, iterations, - std::chrono::milliseconds(0)); - BOTAN_ASSERT_EQUAL(iterations, iterations_run, "Expected PBKDF iterations"); - } - -secure_vector PBKDF::pbkdf_iterations(size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - size_t iterations) const - { - secure_vector out(out_len); - pbkdf_iterations(out.data(), out_len, passphrase, salt, salt_len, iterations); - return out; - } - -secure_vector PBKDF::pbkdf_timed(size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - std::chrono::milliseconds msec, - size_t& iterations) const - { - secure_vector out(out_len); - pbkdf_timed(out.data(), out_len, passphrase, salt, salt_len, msec, iterations); - return out; - } + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + return nullptr; } -/* -* (C) 2018 Ribose Inc -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +// static +std::unique_ptr PBKDF::create_or_throw(const std::string& algo, + const std::string& provider) { + if (auto pbkdf = PBKDF::create(algo, provider)) { + return pbkdf; + } + throw Lookup_Error("PBKDF", algo, provider); +} + +std::vector PBKDF::providers(const std::string& algo_spec) { + return probe_providers_of(algo_spec, {"base", "openssl"}); +} + +void PBKDF::pbkdf_timed(uint8_t out[], size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, std::chrono::milliseconds msec, + size_t& iterations) const { + iterations = pbkdf(out, out_len, passphrase, salt, salt_len, 0, msec); +} + +void PBKDF::pbkdf_iterations(uint8_t out[], size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, size_t iterations) const { + if (iterations == 0) throw Invalid_Argument(name() + ": Invalid iteration count"); + + const size_t iterations_run = + pbkdf(out, out_len, passphrase, salt, salt_len, iterations, std::chrono::milliseconds(0)); + BOTAN_ASSERT_EQUAL(iterations, iterations_run, "Expected PBKDF iterations"); +} + +secure_vector PBKDF::pbkdf_iterations(size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations) const { + secure_vector out(out_len); + pbkdf_iterations(out.data(), out_len, passphrase, salt, salt_len, iterations); + return out; +} + +secure_vector PBKDF::pbkdf_timed(size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + std::chrono::milliseconds msec, + size_t& iterations) const { + secure_vector out(out_len); + pbkdf_timed(out.data(), out_len, passphrase, salt, salt_len, msec, iterations); + return out; +} + +} // namespace Botan +/* + * (C) 2018 Ribose Inc + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_PBKDF2) #endif @@ -20934,322 +18998,251 @@ secure_vector PBKDF::pbkdf_timed(size_t out_len, namespace Botan { std::unique_ptr PasswordHashFamily::create(const std::string& algo_spec, - const std::string& provider) - { - const SCAN_Name req(algo_spec); + const std::string& provider) { + const SCAN_Name req(algo_spec); #if defined(BOTAN_HAS_PBKDF2) - if(req.algo_name() == "PBKDF2") - { - // TODO OpenSSL + if (req.algo_name() == "PBKDF2") { + // TODO OpenSSL - if(provider.empty() || provider == "base") - { - if(auto mac = MessageAuthenticationCode::create(req.arg(0))) - return std::unique_ptr(new PBKDF2_Family(mac.release())); + if (provider.empty() || provider == "base") { + if (auto mac = MessageAuthenticationCode::create(req.arg(0))) + return std::unique_ptr(new PBKDF2_Family(mac.release())); - if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) - return std::unique_ptr(new PBKDF2_Family(mac.release())); - } + if (auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) + return std::unique_ptr(new PBKDF2_Family(mac.release())); + } - return nullptr; - } + return nullptr; + } #endif #if defined(BOTAN_HAS_SCRYPT) - if(req.algo_name() == "Scrypt") - { - return std::unique_ptr(new Scrypt_Family); - } + if (req.algo_name() == "Scrypt") { + return std::unique_ptr(new Scrypt_Family); + } #endif #if defined(BOTAN_HAS_ARGON2) - if(req.algo_name() == "Argon2d") - { - return std::unique_ptr(new Argon2_Family(0)); - } - else if(req.algo_name() == "Argon2i") - { - return std::unique_ptr(new Argon2_Family(1)); - } - else if(req.algo_name() == "Argon2id") - { - return std::unique_ptr(new Argon2_Family(2)); - } + if (req.algo_name() == "Argon2d") { + return std::unique_ptr(new Argon2_Family(0)); + } else if (req.algo_name() == "Argon2i") { + return std::unique_ptr(new Argon2_Family(1)); + } else if (req.algo_name() == "Argon2id") { + return std::unique_ptr(new Argon2_Family(2)); + } #endif #if defined(BOTAN_HAS_PBKDF_BCRYPT) - if(req.algo_name() == "Bcrypt-PBKDF") - { - return std::unique_ptr(new Bcrypt_PBKDF_Family); - } + if (req.algo_name() == "Bcrypt-PBKDF") { + return std::unique_ptr(new Bcrypt_PBKDF_Family); + } #endif #if defined(BOTAN_HAS_PGP_S2K) - if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) - { - if(auto hash = HashFunction::create(req.arg(0))) - { - return std::unique_ptr(new RFC4880_S2K_Family(hash.release())); - } - } + if (req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) { + if (auto hash = HashFunction::create(req.arg(0))) { + return std::unique_ptr(new RFC4880_S2K_Family(hash.release())); + } + } #endif - BOTAN_UNUSED(req); - BOTAN_UNUSED(provider); - - return nullptr; - } - -//static -std::unique_ptr -PasswordHashFamily::create_or_throw(const std::string& algo, - const std::string& provider) - { - if(auto pbkdf = PasswordHashFamily::create(algo, provider)) - { - return pbkdf; - } - throw Lookup_Error("PasswordHashFamily", algo, provider); - } - -std::vector PasswordHashFamily::providers(const std::string& algo_spec) - { - return probe_providers_of(algo_spec, { "base", "openssl" }); - } + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + return nullptr; } -/* -* PBKDF2 -* (C) 1999-2007 Jack Lloyd -* (C) 2018 Ribose Inc -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +// static +std::unique_ptr PasswordHashFamily::create_or_throw( + const std::string& algo, const std::string& provider) { + if (auto pbkdf = PasswordHashFamily::create(algo, provider)) { + return pbkdf; + } + throw Lookup_Error("PasswordHashFamily", algo, provider); +} + +std::vector PasswordHashFamily::providers(const std::string& algo_spec) { + return probe_providers_of(algo_spec, {"base", "openssl"}); +} + +} // namespace Botan +/* + * PBKDF2 + * (C) 1999-2007 Jack Lloyd + * (C) 2018 Ribose Inc + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { -void pbkdf2_set_key(MessageAuthenticationCode& prf, - const char* password, - size_t password_len) - { - try - { - prf.set_key(cast_char_ptr_to_uint8(password), password_len); - } - catch(Invalid_Key_Length&) - { - throw Invalid_Argument("PBKDF2 cannot accept passphrase of the given size"); - } - } - +void pbkdf2_set_key(MessageAuthenticationCode& prf, const char* password, size_t password_len) { + try { + prf.set_key(cast_char_ptr_to_uint8(password), password_len); + } catch (Invalid_Key_Length&) { + throw Invalid_Argument("PBKDF2 cannot accept passphrase of the given size"); + } } -size_t -pbkdf2(MessageAuthenticationCode& prf, - uint8_t out[], - size_t out_len, - const std::string& password, - const uint8_t salt[], size_t salt_len, - size_t iterations, - std::chrono::milliseconds msec) - { - if(iterations == 0) - { - iterations = PBKDF2(prf, out_len, msec).iterations(); - } +} // namespace - PBKDF2 pbkdf2(prf, iterations); +size_t pbkdf2(MessageAuthenticationCode& prf, uint8_t out[], size_t out_len, + const std::string& password, const uint8_t salt[], size_t salt_len, size_t iterations, + std::chrono::milliseconds msec) { + if (iterations == 0) { + iterations = PBKDF2(prf, out_len, msec).iterations(); + } - pbkdf2.derive_key(out, out_len, - password.c_str(), password.size(), - salt, salt_len); + PBKDF2 pbkdf2(prf, iterations); - return iterations; - } + pbkdf2.derive_key(out, out_len, password.c_str(), password.size(), salt, salt_len); + + return iterations; +} namespace { -size_t tune_pbkdf2(MessageAuthenticationCode& prf, - size_t output_length, - uint32_t msec) - { - if(output_length == 0) - output_length = 1; +size_t tune_pbkdf2(MessageAuthenticationCode& prf, size_t output_length, uint32_t msec) { + if (output_length == 0) output_length = 1; - const size_t prf_sz = prf.output_length(); - BOTAN_ASSERT_NOMSG(prf_sz > 0); - secure_vector U(prf_sz); + const size_t prf_sz = prf.output_length(); + BOTAN_ASSERT_NOMSG(prf_sz > 0); + secure_vector U(prf_sz); - const size_t trial_iterations = 2000; + const size_t trial_iterations = 2000; - // Short output ensures we only need a single PBKDF2 block + // Short output ensures we only need a single PBKDF2 block - Timer timer("PBKDF2"); + Timer timer("PBKDF2"); - const auto tune_time = BOTAN_PBKDF_TUNING_TIME; + const auto tune_time = BOTAN_PBKDF_TUNING_TIME; - prf.set_key(nullptr, 0); + prf.set_key(nullptr, 0); - timer.run_until_elapsed(tune_time, [&]() { - uint8_t out[12] = { 0 }; - uint8_t salt[12] = { 0 }; - pbkdf2(prf, out, sizeof(out), salt, sizeof(salt), trial_iterations); - }); + timer.run_until_elapsed(tune_time, [&]() { + uint8_t out[12] = {0}; + uint8_t salt[12] = {0}; + pbkdf2(prf, out, sizeof(out), salt, sizeof(salt), trial_iterations); + }); - if(timer.events() == 0) - return trial_iterations; + if (timer.events() == 0) return trial_iterations; - const uint64_t duration_nsec = timer.value() / timer.events(); + const uint64_t duration_nsec = timer.value() / timer.events(); - const uint64_t desired_nsec = static_cast(msec) * 1000000; + const uint64_t desired_nsec = static_cast(msec) * 1000000; - if(duration_nsec > desired_nsec) - return trial_iterations; + if (duration_nsec > desired_nsec) return trial_iterations; - const size_t blocks_needed = (output_length + prf_sz - 1) / prf_sz; + const size_t blocks_needed = (output_length + prf_sz - 1) / prf_sz; - const size_t multiplier = static_cast(desired_nsec / duration_nsec / blocks_needed); - - if(multiplier == 0) - return trial_iterations; - else - return trial_iterations * multiplier; - } + const size_t multiplier = static_cast(desired_nsec / duration_nsec / blocks_needed); + if (multiplier == 0) + return trial_iterations; + else + return trial_iterations * multiplier; } -void pbkdf2(MessageAuthenticationCode& prf, - uint8_t out[], - size_t out_len, - const uint8_t salt[], - size_t salt_len, - size_t iterations) - { - if(iterations == 0) - throw Invalid_Argument("PBKDF2: Invalid iteration count"); +} // namespace - clear_mem(out, out_len); +void pbkdf2(MessageAuthenticationCode& prf, uint8_t out[], size_t out_len, const uint8_t salt[], + size_t salt_len, size_t iterations) { + if (iterations == 0) throw Invalid_Argument("PBKDF2: Invalid iteration count"); - if(out_len == 0) - return; + clear_mem(out, out_len); - const size_t prf_sz = prf.output_length(); - BOTAN_ASSERT_NOMSG(prf_sz > 0); + if (out_len == 0) return; - secure_vector U(prf_sz); + const size_t prf_sz = prf.output_length(); + BOTAN_ASSERT_NOMSG(prf_sz > 0); - uint32_t counter = 1; - while(out_len) - { - const size_t prf_output = std::min(prf_sz, out_len); + secure_vector U(prf_sz); - prf.update(salt, salt_len); - prf.update_be(counter++); - prf.final(U.data()); + uint32_t counter = 1; + while (out_len) { + const size_t prf_output = std::min(prf_sz, out_len); - xor_buf(out, U.data(), prf_output); + prf.update(salt, salt_len); + prf.update_be(counter++); + prf.final(U.data()); - for(size_t i = 1; i != iterations; ++i) - { - prf.update(U); - prf.final(U.data()); - xor_buf(out, U.data(), prf_output); - } + xor_buf(out, U.data(), prf_output); - out_len -= prf_output; - out += prf_output; - } - } + for (size_t i = 1; i != iterations; ++i) { + prf.update(U); + prf.final(U.data()); + xor_buf(out, U.data(), prf_output); + } + + out_len -= prf_output; + out += prf_output; + } +} // PBKDF interface -size_t -PKCS5_PBKDF2::pbkdf(uint8_t key[], size_t key_len, - const std::string& password, - const uint8_t salt[], size_t salt_len, - size_t iterations, - std::chrono::milliseconds msec) const - { - if(iterations == 0) - { - iterations = PBKDF2(*m_mac, key_len, msec).iterations(); - } +size_t PKCS5_PBKDF2::pbkdf(uint8_t key[], size_t key_len, const std::string& password, + const uint8_t salt[], size_t salt_len, size_t iterations, + std::chrono::milliseconds msec) const { + if (iterations == 0) { + iterations = PBKDF2(*m_mac, key_len, msec).iterations(); + } - PBKDF2 pbkdf2(*m_mac, iterations); + PBKDF2 pbkdf2(*m_mac, iterations); - pbkdf2.derive_key(key, key_len, - password.c_str(), password.size(), - salt, salt_len); + pbkdf2.derive_key(key, key_len, password.c_str(), password.size(), salt, salt_len); - return iterations; - } + return iterations; +} -std::string PKCS5_PBKDF2::name() const - { - return "PBKDF2(" + m_mac->name() + ")"; - } +std::string PKCS5_PBKDF2::name() const { return "PBKDF2(" + m_mac->name() + ")"; } -PBKDF* PKCS5_PBKDF2::clone() const - { - return new PKCS5_PBKDF2(m_mac->clone()); - } +PBKDF* PKCS5_PBKDF2::clone() const { return new PKCS5_PBKDF2(m_mac->clone()); } // PasswordHash interface -PBKDF2::PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec) : - m_prf(prf.clone()), - m_iterations(tune_pbkdf2(*m_prf, olen, static_cast(msec.count()))) - {} - -std::string PBKDF2::to_string() const - { - return "PBKDF2(" + m_prf->name() + "," + std::to_string(m_iterations) + ")"; - } - -void PBKDF2::derive_key(uint8_t out[], size_t out_len, - const char* password, const size_t password_len, - const uint8_t salt[], size_t salt_len) const - { - pbkdf2_set_key(*m_prf, password, password_len); - pbkdf2(*m_prf, out, out_len, salt, salt_len, m_iterations); - } - -std::string PBKDF2_Family::name() const - { - return "PBKDF2(" + m_prf->name() + ")"; - } - -std::unique_ptr PBKDF2_Family::tune(size_t output_len, std::chrono::milliseconds msec, size_t) const - { - return std::unique_ptr(new PBKDF2(*m_prf, output_len, msec)); - } - -std::unique_ptr PBKDF2_Family::default_params() const - { - return std::unique_ptr(new PBKDF2(*m_prf, 150000)); - } - -std::unique_ptr PBKDF2_Family::from_params(size_t iter, size_t, size_t) const - { - return std::unique_ptr(new PBKDF2(*m_prf, iter)); - } - -std::unique_ptr PBKDF2_Family::from_iterations(size_t iter) const - { - return std::unique_ptr(new PBKDF2(*m_prf, iter)); - } +PBKDF2::PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec) + : m_prf(prf.clone()), + m_iterations(tune_pbkdf2(*m_prf, olen, static_cast(msec.count()))) {} +std::string PBKDF2::to_string() const { + return "PBKDF2(" + m_prf->name() + "," + std::to_string(m_iterations) + ")"; } -/* -* PEM Encoding/Decoding -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +void PBKDF2::derive_key(uint8_t out[], size_t out_len, const char* password, + const size_t password_len, const uint8_t salt[], size_t salt_len) const { + pbkdf2_set_key(*m_prf, password, password_len); + pbkdf2(*m_prf, out, out_len, salt, salt_len, m_iterations); +} + +std::string PBKDF2_Family::name() const { return "PBKDF2(" + m_prf->name() + ")"; } + +std::unique_ptr PBKDF2_Family::tune(size_t output_len, std::chrono::milliseconds msec, + size_t) const { + return std::unique_ptr(new PBKDF2(*m_prf, output_len, msec)); +} + +std::unique_ptr PBKDF2_Family::default_params() const { + return std::unique_ptr(new PBKDF2(*m_prf, 150000)); +} + +std::unique_ptr PBKDF2_Family::from_params(size_t iter, size_t, size_t) const { + return std::unique_ptr(new PBKDF2(*m_prf, iter)); +} + +std::unique_ptr PBKDF2_Family::from_iterations(size_t iter) const { + return std::unique_ptr(new PBKDF2(*m_prf, iter)); +} + +} // namespace Botan +/* + * PEM Encoding/Decoding + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { @@ -21257,164 +19250,138 @@ namespace PEM_Code { namespace { -std::string linewrap(size_t width, const std::string& in) - { - std::string out; - for(size_t i = 0; i != in.size(); ++i) - { - if(i > 0 && i % width == 0) - { - out.push_back('\n'); - } - out.push_back(in[i]); - } - if(out.size() > 0 && out[out.size()-1] != '\n') - { - out.push_back('\n'); - } +std::string linewrap(size_t width, const std::string& in) { + std::string out; + for (size_t i = 0; i != in.size(); ++i) { + if (i > 0 && i % width == 0) { + out.push_back('\n'); + } + out.push_back(in[i]); + } + if (out.size() > 0 && out[out.size() - 1] != '\n') { + out.push_back('\n'); + } - return out; - } + return out; +} +} // namespace + +/* + * PEM encode BER/DER-encoded objects + */ +std::string encode(const uint8_t der[], size_t length, const std::string& label, size_t width) { + const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n"; + const std::string PEM_TRAILER = "-----END " + label + "-----\n"; + + return (PEM_HEADER + linewrap(width, base64_encode(der, length)) + PEM_TRAILER); } /* -* PEM encode BER/DER-encoded objects -*/ -std::string encode(const uint8_t der[], size_t length, const std::string& label, size_t width) - { - const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n"; - const std::string PEM_TRAILER = "-----END " + label + "-----\n"; - - return (PEM_HEADER + linewrap(width, base64_encode(der, length)) + PEM_TRAILER); - } - -/* -* Decode PEM down to raw BER/DER -*/ -secure_vector decode_check_label(DataSource& source, - const std::string& label_want) - { - std::string label_got; - secure_vector ber = decode(source, label_got); - if(label_got != label_want) - throw Decoding_Error("PEM: Label mismatch, wanted " + label_want + - ", got " + label_got); - return ber; - } - -/* -* Decode PEM down to raw BER/DER -*/ -secure_vector decode(DataSource& source, std::string& label) - { - const size_t RANDOM_CHAR_LIMIT = 8; - - label.clear(); - - const std::string PEM_HEADER1 = "-----BEGIN "; - const std::string PEM_HEADER2 = "-----"; - size_t position = 0; - - while(position != PEM_HEADER1.length()) - { - uint8_t b; - if(!source.read_byte(b)) - throw Decoding_Error("PEM: No PEM header found"); - if(b == PEM_HEADER1[position]) - ++position; - else if(position >= RANDOM_CHAR_LIMIT) - throw Decoding_Error("PEM: Malformed PEM header"); - else - position = 0; - } - position = 0; - while(position != PEM_HEADER2.length()) - { - uint8_t b; - if(!source.read_byte(b)) - throw Decoding_Error("PEM: No PEM header found"); - if(b == PEM_HEADER2[position]) - ++position; - else if(position) - throw Decoding_Error("PEM: Malformed PEM header"); - - if(position == 0) - label += static_cast(b); - } - - std::vector b64; - - const std::string PEM_TRAILER = "-----END " + label + "-----"; - position = 0; - while(position != PEM_TRAILER.length()) - { - uint8_t b; - if(!source.read_byte(b)) - throw Decoding_Error("PEM: No PEM trailer found"); - if(b == PEM_TRAILER[position]) - ++position; - else if(position) - throw Decoding_Error("PEM: Malformed PEM trailer"); - - if(position == 0) - b64.push_back(b); - } - - return base64_decode(b64.data(), b64.size()); - } - -secure_vector decode_check_label(const std::string& pem, - const std::string& label_want) - { - DataSource_Memory src(pem); - return decode_check_label(src, label_want); - } - -secure_vector decode(const std::string& pem, std::string& label) - { - DataSource_Memory src(pem); - return decode(src, label); - } - -/* -* Search for a PEM signature -*/ -bool matches(DataSource& source, const std::string& extra, - size_t search_range) - { - const std::string PEM_HEADER = "-----BEGIN " + extra; - - secure_vector search_buf(search_range); - size_t got = source.peek(search_buf.data(), search_buf.size(), 0); - - if(got < PEM_HEADER.length()) - return false; - - size_t index = 0; - - for(size_t j = 0; j != got; ++j) - { - if(search_buf[j] == PEM_HEADER[index]) - ++index; - else - index = 0; - if(index == PEM_HEADER.size()) - return true; - } - return false; - } - + * Decode PEM down to raw BER/DER + */ +secure_vector decode_check_label(DataSource& source, const std::string& label_want) { + std::string label_got; + secure_vector ber = decode(source, label_got); + if (label_got != label_want) + throw Decoding_Error("PEM: Label mismatch, wanted " + label_want + ", got " + label_got); + return ber; } -} /* -* EME Base Class -* (C) 1999-2008 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Decode PEM down to raw BER/DER + */ +secure_vector decode(DataSource& source, std::string& label) { + const size_t RANDOM_CHAR_LIMIT = 8; + label.clear(); + + const std::string PEM_HEADER1 = "-----BEGIN "; + const std::string PEM_HEADER2 = "-----"; + size_t position = 0; + + while (position != PEM_HEADER1.length()) { + uint8_t b; + if (!source.read_byte(b)) throw Decoding_Error("PEM: No PEM header found"); + if (b == PEM_HEADER1[position]) + ++position; + else if (position >= RANDOM_CHAR_LIMIT) + throw Decoding_Error("PEM: Malformed PEM header"); + else + position = 0; + } + position = 0; + while (position != PEM_HEADER2.length()) { + uint8_t b; + if (!source.read_byte(b)) throw Decoding_Error("PEM: No PEM header found"); + if (b == PEM_HEADER2[position]) + ++position; + else if (position) + throw Decoding_Error("PEM: Malformed PEM header"); + + if (position == 0) label += static_cast(b); + } + + std::vector b64; + + const std::string PEM_TRAILER = "-----END " + label + "-----"; + position = 0; + while (position != PEM_TRAILER.length()) { + uint8_t b; + if (!source.read_byte(b)) throw Decoding_Error("PEM: No PEM trailer found"); + if (b == PEM_TRAILER[position]) + ++position; + else if (position) + throw Decoding_Error("PEM: Malformed PEM trailer"); + + if (position == 0) b64.push_back(b); + } + + return base64_decode(b64.data(), b64.size()); +} + +secure_vector decode_check_label(const std::string& pem, const std::string& label_want) { + DataSource_Memory src(pem); + return decode_check_label(src, label_want); +} + +secure_vector decode(const std::string& pem, std::string& label) { + DataSource_Memory src(pem); + return decode(src, label); +} + +/* + * Search for a PEM signature + */ +bool matches(DataSource& source, const std::string& extra, size_t search_range) { + const std::string PEM_HEADER = "-----BEGIN " + extra; + + secure_vector search_buf(search_range); + size_t got = source.peek(search_buf.data(), search_buf.size(), 0); + + if (got < PEM_HEADER.length()) return false; + + size_t index = 0; + + for (size_t j = 0; j != got; ++j) { + if (search_buf[j] == PEM_HEADER[index]) + ++index; + else + index = 0; + if (index == PEM_HEADER.size()) return true; + } + return false; +} + +} // namespace PEM_Code + +} // namespace Botan +/* + * EME Base Class + * (C) 1999-2008 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_EME_OAEP) #endif @@ -21427,494 +19394,399 @@ bool matches(DataSource& source, const std::string& extra, namespace Botan { -EME* get_eme(const std::string& algo_spec) - { +EME* get_eme(const std::string& algo_spec) { #if defined(BOTAN_HAS_EME_RAW) - if(algo_spec == "Raw") - return new EME_Raw; + if (algo_spec == "Raw") return new EME_Raw; #endif #if defined(BOTAN_HAS_EME_PKCS1) - if(algo_spec == "PKCS1v15" || algo_spec == "EME-PKCS1-v1_5") - return new EME_PKCS1v15; + if (algo_spec == "PKCS1v15" || algo_spec == "EME-PKCS1-v1_5") return new EME_PKCS1v15; #endif #if defined(BOTAN_HAS_EME_OAEP) - SCAN_Name req(algo_spec); + SCAN_Name req(algo_spec); - if(req.algo_name() == "OAEP" || - req.algo_name() == "EME-OAEP" || - req.algo_name() == "EME1") - { - if(req.arg_count() == 1 || - ((req.arg_count() == 2 || req.arg_count() == 3) && req.arg(1) == "MGF1")) - { - if(auto hash = HashFunction::create(req.arg(0))) - return new OAEP(hash.release(), req.arg(2, "")); - } - else if(req.arg_count() == 2 || req.arg_count() == 3) - { - auto mgf_params = parse_algorithm_name(req.arg(1)); + if (req.algo_name() == "OAEP" || req.algo_name() == "EME-OAEP" || req.algo_name() == "EME1") { + if (req.arg_count() == 1 || + ((req.arg_count() == 2 || req.arg_count() == 3) && req.arg(1) == "MGF1")) { + if (auto hash = HashFunction::create(req.arg(0))) + return new OAEP(hash.release(), req.arg(2, "")); + } else if (req.arg_count() == 2 || req.arg_count() == 3) { + auto mgf_params = parse_algorithm_name(req.arg(1)); - if(mgf_params.size() == 2 && mgf_params[0] == "MGF1") - { + if (mgf_params.size() == 2 && mgf_params[0] == "MGF1") { + auto hash = HashFunction::create(req.arg(0)); + auto mgf1_hash = HashFunction::create(mgf_params[1]); + + if (hash && mgf1_hash) { + return new OAEP(hash.release(), mgf1_hash.release(), req.arg(2, "")); + } + } + } + } +#endif + + throw Algorithm_Not_Found(algo_spec); +} + +/* + * Encode a message + */ +secure_vector EME::encode(const uint8_t msg[], size_t msg_len, size_t key_bits, + RandomNumberGenerator& rng) const { + return pad(msg, msg_len, key_bits, rng); +} + +/* + * Encode a message + */ +secure_vector EME::encode(const secure_vector& msg, size_t key_bits, + RandomNumberGenerator& rng) const { + return pad(msg.data(), msg.size(), key_bits, rng); +} + +} // namespace Botan +/* + * (C) 2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +#if defined(BOTAN_HAS_EMSA1) +#endif + +#if defined(BOTAN_HAS_EMSA_X931) +#endif + +#if defined(BOTAN_HAS_EMSA_PKCS1) +#endif + +#if defined(BOTAN_HAS_EMSA_PSSR) +#endif + +#if defined(BOTAN_HAS_EMSA_RAW) +#endif + +#if defined(BOTAN_HAS_ISO_9796) +#endif + +namespace Botan { + +AlgorithmIdentifier EMSA::config_for_x509(const Private_Key&, const std::string&) const { + throw Not_Implemented("Encoding " + name() + " not supported for signing X509 objects"); +} + +EMSA* get_emsa(const std::string& algo_spec) { + SCAN_Name req(algo_spec); + +#if defined(BOTAN_HAS_EMSA1) + if (req.algo_name() == "EMSA1" && req.arg_count() == 1) { + if (auto hash = HashFunction::create(req.arg(0))) return new EMSA1(hash.release()); + } +#endif + +#if defined(BOTAN_HAS_EMSA_PKCS1) + if (req.algo_name() == "EMSA_PKCS1" || req.algo_name() == "PKCS1v15" || + req.algo_name() == "EMSA-PKCS1-v1_5" || req.algo_name() == "EMSA3") { + if (req.arg_count() == 2 && req.arg(0) == "Raw") { + return new EMSA_PKCS1v15_Raw(req.arg(1)); + } else if (req.arg_count() == 1) { + if (req.arg(0) == "Raw") { + return new EMSA_PKCS1v15_Raw; + } else { + if (auto hash = HashFunction::create(req.arg(0))) { + return new EMSA_PKCS1v15(hash.release()); + } + } + } + } +#endif + +#if defined(BOTAN_HAS_EMSA_PSSR) + if (req.algo_name() == "PSS_Raw" || req.algo_name() == "PSSR_Raw") { + if (req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") { + if (auto h = HashFunction::create(req.arg(0))) { + if (req.arg_count() == 3) { + const size_t salt_size = req.arg_as_integer(2, 0); + return new PSSR_Raw(h.release(), salt_size); + } else { + return new PSSR_Raw(h.release()); + } + } + } + } + + if (req.algo_name() == "PSS" || req.algo_name() == "PSSR" || req.algo_name() == "EMSA-PSS" || + req.algo_name() == "PSS-MGF1" || req.algo_name() == "EMSA4") { + if (req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") { + if (auto h = HashFunction::create(req.arg(0))) { + if (req.arg_count() == 3) { + const size_t salt_size = req.arg_as_integer(2, 0); + return new PSSR(h.release(), salt_size); + } else { + return new PSSR(h.release()); + } + } + } + } +#endif + +#if defined(BOTAN_HAS_ISO_9796) + if (req.algo_name() == "ISO_9796_DS2") { + if (req.arg_count_between(1, 3)) { + if (auto h = HashFunction::create(req.arg(0))) { + const size_t salt_size = req.arg_as_integer(2, h->output_length()); + const bool implicit = req.arg(1, "exp") == "imp"; + return new ISO_9796_DS2(h.release(), implicit, salt_size); + } + } + } + // ISO-9796-2 DS 3 is deterministic and DS2 without a salt + if (req.algo_name() == "ISO_9796_DS3") { + if (req.arg_count_between(1, 2)) { + if (auto h = HashFunction::create(req.arg(0))) { + const bool implicit = req.arg(1, "exp") == "imp"; + return new ISO_9796_DS3(h.release(), implicit); + } + } + } +#endif + +#if defined(BOTAN_HAS_EMSA_X931) + if (req.algo_name() == "EMSA_X931" || req.algo_name() == "EMSA2" || + req.algo_name() == "X9.31") { + if (req.arg_count() == 1) { + if (auto hash = HashFunction::create(req.arg(0))) { + return new EMSA_X931(hash.release()); + } + } + } +#endif + +#if defined(BOTAN_HAS_EMSA_RAW) + if (req.algo_name() == "Raw") { + if (req.arg_count() == 0) { + return new EMSA_Raw; + } else { auto hash = HashFunction::create(req.arg(0)); - auto mgf1_hash = HashFunction::create(mgf_params[1]); - - if(hash && mgf1_hash) - { - return new OAEP(hash.release(), mgf1_hash.release(), req.arg(2, "")); - } - } - } - } + if (hash) return new EMSA_Raw(hash->output_length()); + } + } #endif - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Encode a message -*/ -secure_vector EME::encode(const uint8_t msg[], size_t msg_len, - size_t key_bits, - RandomNumberGenerator& rng) const - { - return pad(msg, msg_len, key_bits, rng); - } - -/* -* Encode a message -*/ -secure_vector EME::encode(const secure_vector& msg, - size_t key_bits, - RandomNumberGenerator& rng) const - { - return pad(msg.data(), msg.size(), key_bits, rng); - } - - + throw Algorithm_Not_Found(algo_spec); } -/* -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +std::string hash_for_emsa(const std::string& algo_spec) { + SCAN_Name emsa_name(algo_spec); -#if defined(BOTAN_HAS_EMSA1) -#endif + if (emsa_name.arg_count() > 0) { + const std::string pos_hash = emsa_name.arg(0); + return pos_hash; + } -#if defined(BOTAN_HAS_EMSA_X931) -#endif - -#if defined(BOTAN_HAS_EMSA_PKCS1) -#endif - -#if defined(BOTAN_HAS_EMSA_PSSR) -#endif - -#if defined(BOTAN_HAS_EMSA_RAW) -#endif - -#if defined(BOTAN_HAS_ISO_9796) -#endif - -namespace Botan { - -AlgorithmIdentifier EMSA::config_for_x509(const Private_Key&, - const std::string&) const - { - throw Not_Implemented("Encoding " + name() + " not supported for signing X509 objects"); - } - -EMSA* get_emsa(const std::string& algo_spec) - { - SCAN_Name req(algo_spec); - -#if defined(BOTAN_HAS_EMSA1) - if(req.algo_name() == "EMSA1" && req.arg_count() == 1) - { - if(auto hash = HashFunction::create(req.arg(0))) - return new EMSA1(hash.release()); - } -#endif - -#if defined(BOTAN_HAS_EMSA_PKCS1) - if(req.algo_name() == "EMSA_PKCS1" || - req.algo_name() == "PKCS1v15" || - req.algo_name() == "EMSA-PKCS1-v1_5" || - req.algo_name() == "EMSA3") - { - if(req.arg_count() == 2 && req.arg(0) == "Raw") - { - return new EMSA_PKCS1v15_Raw(req.arg(1)); - } - else if(req.arg_count() == 1) - { - if(req.arg(0) == "Raw") - { - return new EMSA_PKCS1v15_Raw; - } - else - { - if(auto hash = HashFunction::create(req.arg(0))) - { - return new EMSA_PKCS1v15(hash.release()); - } - } - } - } -#endif - -#if defined(BOTAN_HAS_EMSA_PSSR) - if(req.algo_name() == "PSS_Raw" || - req.algo_name() == "PSSR_Raw") - { - if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") - { - if(auto h = HashFunction::create(req.arg(0))) - { - if(req.arg_count() == 3) - { - const size_t salt_size = req.arg_as_integer(2, 0); - return new PSSR_Raw(h.release(), salt_size); - } - else - { - return new PSSR_Raw(h.release()); - } - } - } - } - - if(req.algo_name() == "PSS" || - req.algo_name() == "PSSR" || - req.algo_name() == "EMSA-PSS" || - req.algo_name() == "PSS-MGF1" || - req.algo_name() == "EMSA4") - { - if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") - { - if(auto h = HashFunction::create(req.arg(0))) - { - if(req.arg_count() == 3) - { - const size_t salt_size = req.arg_as_integer(2, 0); - return new PSSR(h.release(), salt_size); - } - else - { - return new PSSR(h.release()); - } - } - } - } -#endif - -#if defined(BOTAN_HAS_ISO_9796) - if(req.algo_name() == "ISO_9796_DS2") - { - if(req.arg_count_between(1, 3)) - { - if(auto h = HashFunction::create(req.arg(0))) - { - const size_t salt_size = req.arg_as_integer(2, h->output_length()); - const bool implicit = req.arg(1, "exp") == "imp"; - return new ISO_9796_DS2(h.release(), implicit, salt_size); - } - } - } - //ISO-9796-2 DS 3 is deterministic and DS2 without a salt - if(req.algo_name() == "ISO_9796_DS3") - { - if(req.arg_count_between(1, 2)) - { - if(auto h = HashFunction::create(req.arg(0))) - { - const bool implicit = req.arg(1, "exp") == "imp"; - return new ISO_9796_DS3(h.release(), implicit); - } - } - } -#endif - -#if defined(BOTAN_HAS_EMSA_X931) - if(req.algo_name() == "EMSA_X931" || - req.algo_name() == "EMSA2" || - req.algo_name() == "X9.31") - { - if(req.arg_count() == 1) - { - if(auto hash = HashFunction::create(req.arg(0))) - { - return new EMSA_X931(hash.release()); - } - } - } -#endif - -#if defined(BOTAN_HAS_EMSA_RAW) - if(req.algo_name() == "Raw") - { - if(req.arg_count() == 0) - { - return new EMSA_Raw; - } - else - { - auto hash = HashFunction::create(req.arg(0)); - if(hash) - return new EMSA_Raw(hash->output_length()); - } - } -#endif - - throw Algorithm_Not_Found(algo_spec); - } - -std::string hash_for_emsa(const std::string& algo_spec) - { - SCAN_Name emsa_name(algo_spec); - - if(emsa_name.arg_count() > 0) - { - const std::string pos_hash = emsa_name.arg(0); - return pos_hash; - } - - // If we don't understand what this is return a safe default + // If we don't understand what this is return a safe default #if defined(BOTAN_HAS_SHA2_64) - return "SHA-512"; + return "SHA-512"; #else - return "SHA-256"; + return "SHA-256"; #endif - } - } -/* -* Sets of allowed padding schemes for public key types -* -* This file was automatically generated by ./src/scripts/oids.py on 2017-12-20 -* -* All manual edits to this file will be lost. Edit the script -* then regenerate this source file. -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * Sets of allowed padding schemes for public key types + * + * This file was automatically generated by ./src/scripts/oids.py on 2017-12-20 + * + * All manual edits to this file will be lost. Edit the script + * then regenerate this source file. + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -const std::map> allowed_signature_paddings = - { - { "DSA", {"EMSA1"} }, - { "ECDSA", {"EMSA1"} }, - { "ECGDSA", {"EMSA1"} }, - { "ECKCDSA", {"EMSA1"} }, - { "GOST-34.10", {"EMSA1"} }, - { "GOST-34.10-2012-256", {"EMSA1"} }, - { "GOST-34.10-2012-512", {"EMSA1"} }, - { "RSA", {"EMSA4", "EMSA3"} }, - }; +const std::map> allowed_signature_paddings = { + {"DSA", {"EMSA1"}}, + {"ECDSA", {"EMSA1"}}, + {"ECGDSA", {"EMSA1"}}, + {"ECKCDSA", {"EMSA1"}}, + {"GOST-34.10", {"EMSA1"}}, + {"GOST-34.10-2012-256", {"EMSA1"}}, + {"GOST-34.10-2012-512", {"EMSA1"}}, + {"RSA", {"EMSA4", "EMSA3"}}, +}; -const std::vector get_sig_paddings(const std::string algo) - { - if(allowed_signature_paddings.count(algo) > 0) - return allowed_signature_paddings.at(algo); - return {}; - } - -bool sig_algo_and_pad_ok(const std::string algo, const std::string padding) - { - std::vector pads = get_sig_paddings(algo); - return std::find(pads.begin(), pads.end(), padding) != pads.end(); - } +const std::vector get_sig_paddings(const std::string algo) { + if (allowed_signature_paddings.count(algo) > 0) return allowed_signature_paddings.at(algo); + return {}; } -/* -* (C) 2017,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +bool sig_algo_and_pad_ok(const std::string algo, const std::string padding) { + std::vector pads = get_sig_paddings(algo); + return std::find(pads.begin(), pads.end(), padding) != pads.end(); +} +} // namespace Botan +/* + * (C) 2017,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { /* -* The minimum weight irreducible binary polynomial of size n -* -* See http://www.hpl.hp.com/techreports/98/HPL-98-135.pdf -*/ + * The minimum weight irreducible binary polynomial of size n + * + * See http://www.hpl.hp.com/techreports/98/HPL-98-135.pdf + */ enum class MinWeightPolynomial : uint64_t { - P64 = 0x1B, - P128 = 0x87, - P192 = 0x87, - P256 = 0x425, - P512 = 0x125, - P1024 = 0x80043, + P64 = 0x1B, + P128 = 0x87, + P192 = 0x87, + P256 = 0x425, + P512 = 0x125, + P1024 = 0x80043, }; -template -void poly_double(uint8_t out[], const uint8_t in[]) - { - uint64_t W[LIMBS]; - load_be(W, in, LIMBS); +template +void poly_double(uint8_t out[], const uint8_t in[]) { + uint64_t W[LIMBS]; + load_be(W, in, LIMBS); - const uint64_t POLY = static_cast(P); + const uint64_t POLY = static_cast(P); - const uint64_t carry = POLY * (W[0] >> 63); + const uint64_t carry = POLY * (W[0] >> 63); - BOTAN_IF_CONSTEXPR(LIMBS > 0) - { - for(size_t i = 0; i != LIMBS - 1; ++i) - W[i] = (W[i] << 1) ^ (W[i+1] >> 63); - } + BOTAN_IF_CONSTEXPR(LIMBS > 0) { + for (size_t i = 0; i != LIMBS - 1; ++i) W[i] = (W[i] << 1) ^ (W[i + 1] >> 63); + } - W[LIMBS-1] = (W[LIMBS-1] << 1) ^ carry; - - copy_out_be(out, LIMBS*8, W); - } - -template -void poly_double_le(uint8_t out[], const uint8_t in[]) - { - uint64_t W[LIMBS]; - load_le(W, in, LIMBS); - - const uint64_t POLY = static_cast(P); - - const uint64_t carry = POLY * (W[LIMBS-1] >> 63); - - BOTAN_IF_CONSTEXPR(LIMBS > 0) - { - for(size_t i = 0; i != LIMBS - 1; ++i) - W[LIMBS-1-i] = (W[LIMBS-1-i] << 1) ^ (W[LIMBS-2-i] >> 63); - } - - W[0] = (W[0] << 1) ^ carry; - - copy_out_le(out, LIMBS*8, W); - } + W[LIMBS - 1] = (W[LIMBS - 1] << 1) ^ carry; + copy_out_be(out, LIMBS * 8, W); } -void poly_double_n(uint8_t out[], const uint8_t in[], size_t n) - { - switch(n) - { - case 8: - return poly_double<1, MinWeightPolynomial::P64>(out, in); - case 16: - return poly_double<2, MinWeightPolynomial::P128>(out, in); - case 24: - return poly_double<3, MinWeightPolynomial::P192>(out, in); - case 32: - return poly_double<4, MinWeightPolynomial::P256>(out, in); - case 64: - return poly_double<8, MinWeightPolynomial::P512>(out, in); - case 128: - return poly_double<16, MinWeightPolynomial::P1024>(out, in); - default: - throw Invalid_Argument("Unsupported size for poly_double_n"); - } - } +template +void poly_double_le(uint8_t out[], const uint8_t in[]) { + uint64_t W[LIMBS]; + load_le(W, in, LIMBS); -void poly_double_n_le(uint8_t out[], const uint8_t in[], size_t n) - { - switch(n) - { - case 8: - return poly_double_le<1, MinWeightPolynomial::P64>(out, in); - case 16: - return poly_double_le<2, MinWeightPolynomial::P128>(out, in); - case 24: - return poly_double_le<3, MinWeightPolynomial::P192>(out, in); - case 32: - return poly_double_le<4, MinWeightPolynomial::P256>(out, in); - case 64: - return poly_double_le<8, MinWeightPolynomial::P512>(out, in); - case 128: - return poly_double_le<16, MinWeightPolynomial::P1024>(out, in); - default: - throw Invalid_Argument("Unsupported size for poly_double_n_le"); - } - } + const uint64_t POLY = static_cast(P); + const uint64_t carry = POLY * (W[LIMBS - 1] >> 63); + + BOTAN_IF_CONSTEXPR(LIMBS > 0) { + for (size_t i = 0; i != LIMBS - 1; ++i) + W[LIMBS - 1 - i] = (W[LIMBS - 1 - i] << 1) ^ (W[LIMBS - 2 - i] >> 63); + } + + W[0] = (W[0] << 1) ^ carry; + + copy_out_le(out, LIMBS * 8, W); } + +} // namespace + +void poly_double_n(uint8_t out[], const uint8_t in[], size_t n) { + switch (n) { + case 8: + return poly_double<1, MinWeightPolynomial::P64>(out, in); + case 16: + return poly_double<2, MinWeightPolynomial::P128>(out, in); + case 24: + return poly_double<3, MinWeightPolynomial::P192>(out, in); + case 32: + return poly_double<4, MinWeightPolynomial::P256>(out, in); + case 64: + return poly_double<8, MinWeightPolynomial::P512>(out, in); + case 128: + return poly_double<16, MinWeightPolynomial::P1024>(out, in); + default: + throw Invalid_Argument("Unsupported size for poly_double_n"); + } +} + +void poly_double_n_le(uint8_t out[], const uint8_t in[], size_t n) { + switch (n) { + case 8: + return poly_double_le<1, MinWeightPolynomial::P64>(out, in); + case 16: + return poly_double_le<2, MinWeightPolynomial::P128>(out, in); + case 24: + return poly_double_le<3, MinWeightPolynomial::P192>(out, in); + case 32: + return poly_double_le<4, MinWeightPolynomial::P256>(out, in); + case 64: + return poly_double_le<8, MinWeightPolynomial::P512>(out, in); + case 128: + return poly_double_le<16, MinWeightPolynomial::P1024>(out, in); + default: + throw Invalid_Argument("Unsupported size for poly_double_n_le"); + } +} + +} // namespace Botan /* -* Blinding for public key operations -* (C) 1999-2010,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Blinding for public key operations + * (C) 1999-2010,2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -Blinder::Blinder(const BigInt& modulus, - RandomNumberGenerator& rng, - std::function fwd, - std::function inv) : - m_reducer(modulus), +Blinder::Blinder(const BigInt& modulus, RandomNumberGenerator& rng, + std::function fwd, std::function inv) + : m_reducer(modulus), m_rng(rng), m_fwd_fn(fwd), m_inv_fn(inv), m_modulus_bits(modulus.bits()), m_e{}, m_d{}, - m_counter{} - { - const BigInt k = blinding_nonce(); - m_e = m_fwd_fn(k); - m_d = m_inv_fn(k); - } - -BigInt Blinder::blinding_nonce() const - { - return BigInt(m_rng, m_modulus_bits - 1); - } - -BigInt Blinder::blind(const BigInt& i) const - { - if(!m_reducer.initialized()) - throw Invalid_State("Blinder not initialized, cannot blind"); - - ++m_counter; - - if((BOTAN_BLINDING_REINIT_INTERVAL > 0) && (m_counter > BOTAN_BLINDING_REINIT_INTERVAL)) - { - const BigInt k = blinding_nonce(); - m_e = m_fwd_fn(k); - m_d = m_inv_fn(k); - m_counter = 0; - } - else - { - m_e = m_reducer.square(m_e); - m_d = m_reducer.square(m_d); - } - - return m_reducer.multiply(i, m_e); - } - -BigInt Blinder::unblind(const BigInt& i) const - { - if(!m_reducer.initialized()) - throw Invalid_State("Blinder not initialized, cannot unblind"); - - return m_reducer.multiply(i, m_d); - } - + m_counter{} { + const BigInt k = blinding_nonce(); + m_e = m_fwd_fn(k); + m_d = m_inv_fn(k); } -/* -* PK Key -* (C) 1999-2010,2016 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +BigInt Blinder::blinding_nonce() const { return BigInt(m_rng, m_modulus_bits - 1); } + +BigInt Blinder::blind(const BigInt& i) const { + if (!m_reducer.initialized()) throw Invalid_State("Blinder not initialized, cannot blind"); + + ++m_counter; + + if ((BOTAN_BLINDING_REINIT_INTERVAL > 0) && (m_counter > BOTAN_BLINDING_REINIT_INTERVAL)) { + const BigInt k = blinding_nonce(); + m_e = m_fwd_fn(k); + m_d = m_inv_fn(k); + m_counter = 0; + } else { + m_e = m_reducer.square(m_e); + m_d = m_reducer.square(m_d); + } + + return m_reducer.multiply(i, m_e); +} + +BigInt Blinder::unblind(const BigInt& i) const { + if (!m_reducer.initialized()) throw Invalid_State("Blinder not initialized, cannot unblind"); + + return m_reducer.multiply(i, m_d); +} + +} // namespace Botan +/* + * PK Key + * (C) 1999-2010,2016 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_RSA) #endif @@ -21969,668 +19841,570 @@ BigInt Blinder::unblind(const BigInt& i) const namespace Botan { -std::unique_ptr -load_public_key(const AlgorithmIdentifier& alg_id, - const std::vector& /*key_bits*/) - { - const std::string oid_str = alg_id.get_oid().to_formatted_string(); - const std::vector alg_info = split_on(oid_str, '/'); - const std::string alg_name = alg_info[0]; +std::unique_ptr load_public_key(const AlgorithmIdentifier& alg_id, + const std::vector& /*key_bits*/) { + const std::string oid_str = alg_id.get_oid().to_formatted_string(); + const std::vector alg_info = split_on(oid_str, '/'); + const std::string alg_name = alg_info[0]; #if defined(BOTAN_HAS_RSA) - if(alg_name == "RSA") - return std::unique_ptr(new RSA_PublicKey(alg_id, key_bits)); + if (alg_name == "RSA") return std::unique_ptr(new RSA_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_CURVE_25519) - if(alg_name == "Curve25519") - return std::unique_ptr(new Curve25519_PublicKey(alg_id, key_bits)); + if (alg_name == "Curve25519") + return std::unique_ptr(new Curve25519_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_MCELIECE) - if(alg_name == "McEliece") - return std::unique_ptr(new McEliece_PublicKey(key_bits)); + if (alg_name == "McEliece") + return std::unique_ptr(new McEliece_PublicKey(key_bits)); #endif #if defined(BOTAN_HAS_ECDSA) - if(alg_name == "ECDSA") - return std::unique_ptr(new ECDSA_PublicKey(alg_id, key_bits)); + if (alg_name == "ECDSA") + return std::unique_ptr(new ECDSA_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ECDH) - if(alg_name == "ECDH") - return std::unique_ptr(new ECDH_PublicKey(alg_id, key_bits)); + if (alg_name == "ECDH") + return std::unique_ptr(new ECDH_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(alg_name == "DH") - return std::unique_ptr(new DH_PublicKey(alg_id, key_bits)); + if (alg_name == "DH") return std::unique_ptr(new DH_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_DSA) - if(alg_name == "DSA") - return std::unique_ptr(new DSA_PublicKey(alg_id, key_bits)); + if (alg_name == "DSA") return std::unique_ptr(new DSA_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ELGAMAL) - if(alg_name == "ElGamal") - return std::unique_ptr(new ElGamal_PublicKey(alg_id, key_bits)); + if (alg_name == "ElGamal") + return std::unique_ptr(new ElGamal_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ECGDSA) - if(alg_name == "ECGDSA") - return std::unique_ptr(new ECGDSA_PublicKey(alg_id, key_bits)); + if (alg_name == "ECGDSA") + return std::unique_ptr(new ECGDSA_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ECKCDSA) - if(alg_name == "ECKCDSA") - return std::unique_ptr(new ECKCDSA_PublicKey(alg_id, key_bits)); + if (alg_name == "ECKCDSA") + return std::unique_ptr(new ECKCDSA_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ED25519) - if(alg_name == "Ed25519") - return std::unique_ptr(new Ed25519_PublicKey(alg_id, key_bits)); + if (alg_name == "Ed25519") + return std::unique_ptr(new Ed25519_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_GOST_34_10_2001) - if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") - return std::unique_ptr(new GOST_3410_PublicKey(alg_id, key_bits)); + if (alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || + alg_name == "GOST-34.10-2012-512") + return std::unique_ptr(new GOST_3410_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") - return std::unique_ptr(new SM2_PublicKey(alg_id, key_bits)); + if (alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr(new SM2_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_XMSS_RFC8391) - if(alg_name == "XMSS") - return std::unique_ptr(new XMSS_PublicKey(key_bits)); + if (alg_name == "XMSS") return std::unique_ptr(new XMSS_PublicKey(key_bits)); #endif - throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name); - } + throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name); +} -std::unique_ptr -load_private_key(const AlgorithmIdentifier& alg_id, - const secure_vector& /*key_bits*/) - { - const std::string alg_name = alg_id.get_oid().to_formatted_string(); +std::unique_ptr load_private_key(const AlgorithmIdentifier& alg_id, + const secure_vector& /*key_bits*/) { + const std::string alg_name = alg_id.get_oid().to_formatted_string(); #if defined(BOTAN_HAS_RSA) - if(alg_name == "RSA") - return std::unique_ptr(new RSA_PrivateKey(alg_id, key_bits)); + if (alg_name == "RSA") + return std::unique_ptr(new RSA_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_CURVE_25519) - if(alg_name == "Curve25519") - return std::unique_ptr(new Curve25519_PrivateKey(alg_id, key_bits)); + if (alg_name == "Curve25519") + return std::unique_ptr(new Curve25519_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ECDSA) - if(alg_name == "ECDSA") - return std::unique_ptr(new ECDSA_PrivateKey(alg_id, key_bits)); + if (alg_name == "ECDSA") + return std::unique_ptr(new ECDSA_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ECDH) - if(alg_name == "ECDH") - return std::unique_ptr(new ECDH_PrivateKey(alg_id, key_bits)); + if (alg_name == "ECDH") + return std::unique_ptr(new ECDH_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(alg_name == "DH") - return std::unique_ptr(new DH_PrivateKey(alg_id, key_bits)); + if (alg_name == "DH") return std::unique_ptr(new DH_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_DSA) - if(alg_name == "DSA") - return std::unique_ptr(new DSA_PrivateKey(alg_id, key_bits)); + if (alg_name == "DSA") + return std::unique_ptr(new DSA_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_MCELIECE) - if(alg_name == "McEliece") - return std::unique_ptr(new McEliece_PrivateKey(key_bits)); + if (alg_name == "McEliece") + return std::unique_ptr(new McEliece_PrivateKey(key_bits)); #endif #if defined(BOTAN_HAS_ECGDSA) - if(alg_name == "ECGDSA") - return std::unique_ptr(new ECGDSA_PrivateKey(alg_id, key_bits)); + if (alg_name == "ECGDSA") + return std::unique_ptr(new ECGDSA_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ECKCDSA) - if(alg_name == "ECKCDSA") - return std::unique_ptr(new ECKCDSA_PrivateKey(alg_id, key_bits)); + if (alg_name == "ECKCDSA") + return std::unique_ptr(new ECKCDSA_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ED25519) - if(alg_name == "Ed25519") - return std::unique_ptr(new Ed25519_PrivateKey(alg_id, key_bits)); + if (alg_name == "Ed25519") + return std::unique_ptr(new Ed25519_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_GOST_34_10_2001) - if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") - return std::unique_ptr(new GOST_3410_PrivateKey(alg_id, key_bits)); + if (alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || + alg_name == "GOST-34.10-2012-512") + return std::unique_ptr(new GOST_3410_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") - return std::unique_ptr(new SM2_PrivateKey(alg_id, key_bits)); + if (alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr(new SM2_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ELGAMAL) - if(alg_name == "ElGamal") - return std::unique_ptr(new ElGamal_PrivateKey(alg_id, key_bits)); + if (alg_name == "ElGamal") + return std::unique_ptr(new ElGamal_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_XMSS_RFC8391) - if(alg_name == "XMSS") - return std::unique_ptr(new XMSS_PrivateKey(key_bits)); + if (alg_name == "XMSS") return std::unique_ptr(new XMSS_PrivateKey(key_bits)); #endif - throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name); - } + throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name); +} #if defined(BOTAN_HAS_ECC_GROUP) namespace { -std::string default_ec_group_for(const std::string& alg_name) - { - if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") - return "sm2p256v1"; - if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") - return "gost_256A"; - if(alg_name == "GOST-34.10-2012-512") - return "gost_512A"; - if(alg_name == "ECGDSA") - return "brainpool256r1"; - return "secp256r1"; - - } - +std::string default_ec_group_for(const std::string& alg_name) { + if (alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") return "sm2p256v1"; + if (alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") return "gost_256A"; + if (alg_name == "GOST-34.10-2012-512") return "gost_512A"; + if (alg_name == "ECGDSA") return "brainpool256r1"; + return "secp256r1"; } +} // namespace + #endif -std::unique_ptr -create_private_key(const std::string& alg_name, - RandomNumberGenerator& rng, - const std::string& params, - const std::string& provider) - { - /* - * Default paramaters are chosen for work factor > 2**128 where possible - */ +std::unique_ptr create_private_key(const std::string& alg_name, + RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) { + /* + * Default paramaters are chosen for work factor > 2**128 where possible + */ #if defined(BOTAN_HAS_CURVE_25519) - if(alg_name == "Curve25519") - return std::unique_ptr(new Curve25519_PrivateKey(rng)); + if (alg_name == "Curve25519") + return std::unique_ptr(new Curve25519_PrivateKey(rng)); #endif #if defined(BOTAN_HAS_RSA) - if(alg_name == "RSA") - { - const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params)); + if (alg_name == "RSA") { + const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params)); #if defined(BOTAN_HAS_OPENSSL) - if(provider.empty() || provider == "openssl") - { - std::unique_ptr pk; - if((pk = make_openssl_rsa_private_key(rng, rsa_bits))) - return pk; + if (provider.empty() || provider == "openssl") { + std::unique_ptr pk; + if ((pk = make_openssl_rsa_private_key(rng, rsa_bits))) return pk; - if(!provider.empty()) - return nullptr; - } + if (!provider.empty()) return nullptr; + } #endif - return std::unique_ptr(new RSA_PrivateKey(rng, rsa_bits)); - } + return std::unique_ptr(new RSA_PrivateKey(rng, rsa_bits)); + } #endif #if defined(BOTAN_HAS_MCELIECE) - if(alg_name == "McEliece") - { - std::vector mce_param = - Botan::split_on(params.empty() ? "2960,57" : params, ','); + if (alg_name == "McEliece") { + std::vector mce_param = + Botan::split_on(params.empty() ? "2960,57" : params, ','); - if(mce_param.size() != 2) - throw Invalid_Argument("create_private_key bad McEliece parameters " + params); + if (mce_param.size() != 2) + throw Invalid_Argument("create_private_key bad McEliece parameters " + params); - size_t mce_n = Botan::to_u32bit(mce_param[0]); - size_t mce_t = Botan::to_u32bit(mce_param[1]); + size_t mce_n = Botan::to_u32bit(mce_param[0]); + size_t mce_t = Botan::to_u32bit(mce_param[1]); - return std::unique_ptr(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t)); - } + return std::unique_ptr( + new Botan::McEliece_PrivateKey(rng, mce_n, mce_t)); + } #endif #if defined(BOTAN_HAS_XMSS_RFC8391) - if(alg_name == "XMSS") - { - return std::unique_ptr( - new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng)); - } + if (alg_name == "XMSS") { + return std::unique_ptr(new XMSS_PrivateKey( + XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng)); + } #endif #if defined(BOTAN_HAS_ED25519) - if(alg_name == "Ed25519") - { - return std::unique_ptr(new Ed25519_PrivateKey(rng)); - } + if (alg_name == "Ed25519") { + return std::unique_ptr(new Ed25519_PrivateKey(rng)); + } #endif - // ECC crypto + // ECC crypto #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) - if(alg_name == "ECDSA" || - alg_name == "ECDH" || - alg_name == "ECKCDSA" || - alg_name == "ECGDSA" || - alg_name == "SM2" || - alg_name == "SM2_Sig" || - alg_name == "SM2_Enc" || - alg_name == "GOST-34.10" || - alg_name == "GOST-34.10-2012-256" || - alg_name == "GOST-34.10-2012-512") - { - const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params); + if (alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || + alg_name == "ECGDSA" || alg_name == "SM2" || alg_name == "SM2_Sig" || + alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || + alg_name == "GOST-34.10-2012-512") { + const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params); #if defined(BOTAN_HAS_ECDSA) - if(alg_name == "ECDSA") - return std::unique_ptr(new ECDSA_PrivateKey(rng, ec_group)); + if (alg_name == "ECDSA") + return std::unique_ptr(new ECDSA_PrivateKey(rng, ec_group)); #endif #if defined(BOTAN_HAS_ECDH) - if(alg_name == "ECDH") - return std::unique_ptr(new ECDH_PrivateKey(rng, ec_group)); + if (alg_name == "ECDH") + return std::unique_ptr(new ECDH_PrivateKey(rng, ec_group)); #endif #if defined(BOTAN_HAS_ECKCDSA) - if(alg_name == "ECKCDSA") - return std::unique_ptr(new ECKCDSA_PrivateKey(rng, ec_group)); + if (alg_name == "ECKCDSA") + return std::unique_ptr(new ECKCDSA_PrivateKey(rng, ec_group)); #endif #if defined(BOTAN_HAS_GOST_34_10_2001) - if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") - return std::unique_ptr(new GOST_3410_PrivateKey(rng, ec_group)); + if (alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || + alg_name == "GOST-34.10-2012-512") + return std::unique_ptr(new GOST_3410_PrivateKey(rng, ec_group)); #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") - return std::unique_ptr(new SM2_PrivateKey(rng, ec_group)); + if (alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr(new SM2_PrivateKey(rng, ec_group)); #endif #if defined(BOTAN_HAS_ECGDSA) - if(alg_name == "ECGDSA") - return std::unique_ptr(new ECGDSA_PrivateKey(rng, ec_group)); + if (alg_name == "ECGDSA") + return std::unique_ptr(new ECGDSA_PrivateKey(rng, ec_group)); #endif - } + } #endif - // DL crypto + // DL crypto #if defined(BOTAN_HAS_DL_GROUP) - if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") - { - std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048"; - DL_Group modp_group(params.empty() ? default_group : params); + if (alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") { + std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048"; + DL_Group modp_group(params.empty() ? default_group : params); #if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(alg_name == "DH") - return std::unique_ptr(new DH_PrivateKey(rng, modp_group)); + if (alg_name == "DH") + return std::unique_ptr(new DH_PrivateKey(rng, modp_group)); #endif #if defined(BOTAN_HAS_DSA) - if(alg_name == "DSA") - return std::unique_ptr(new DSA_PrivateKey(rng, modp_group)); + if (alg_name == "DSA") + return std::unique_ptr(new DSA_PrivateKey(rng, modp_group)); #endif #if defined(BOTAN_HAS_ELGAMAL) - if(alg_name == "ElGamal") - return std::unique_ptr(new ElGamal_PrivateKey(rng, modp_group)); + if (alg_name == "ElGamal") + return std::unique_ptr(new ElGamal_PrivateKey(rng, modp_group)); #endif - } + } #endif - BOTAN_UNUSED(alg_name, rng, params, provider); + BOTAN_UNUSED(alg_name, rng, params, provider); - return std::unique_ptr(); - } + return std::unique_ptr(); +} -std::vector -probe_provider_private_key(const std::string& alg_name, - const std::vector possible) - { - std::vector providers; - for(auto&& prov : possible) - { - if(prov == "base" || +std::vector probe_provider_private_key(const std::string& alg_name, + const std::vector possible) { + std::vector providers; + for (auto&& prov : possible) { + if (prov == "base" || #if defined(BOTAN_HAS_OPENSSL) - (prov == "openssl" && alg_name == "RSA") || + (prov == "openssl" && alg_name == "RSA") || #endif - 0) - { - providers.push_back(prov); // available - } - } + 0) { + providers.push_back(prov); // available + } + } - BOTAN_UNUSED(alg_name); + BOTAN_UNUSED(alg_name); - return providers; - } + return providers; } +} // namespace Botan /* -* PK Key Types -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * PK Key Types + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -std::string create_hex_fingerprint(const uint8_t bits[], - size_t bits_len, - const std::string& hash_name) - { - std::unique_ptr hash_fn(HashFunction::create_or_throw(hash_name)); - const std::string hex_hash = hex_encode(hash_fn->process(bits, bits_len)); +std::string create_hex_fingerprint(const uint8_t bits[], size_t bits_len, + const std::string& hash_name) { + std::unique_ptr hash_fn(HashFunction::create_or_throw(hash_name)); + const std::string hex_hash = hex_encode(hash_fn->process(bits, bits_len)); - std::string fprint; + std::string fprint; - for(size_t i = 0; i != hex_hash.size(); i += 2) - { - if(i != 0) - fprint.push_back(':'); + for (size_t i = 0; i != hex_hash.size(); i += 2) { + if (i != 0) fprint.push_back(':'); - fprint.push_back(hex_hash[i]); - fprint.push_back(hex_hash[i+1]); - } - - return fprint; - } - -std::vector Public_Key::subject_public_key() const - { - std::vector output; - - DER_Encoder(output).start_cons(SEQUENCE) - .encode(algorithm_identifier()) - .encode(public_key_bits(), BIT_STRING) - .end_cons(); - - return output; - } - -/* -* Default OID access -*/ -OID Public_Key::get_oid() const - { - const OID o = OIDS::str2oid_or_empty(algo_name()); - if(o.empty()) - throw Lookup_Error("PK algo " + algo_name() + " has no defined OIDs"); - return o; - } - -secure_vector Private_Key::private_key_info() const - { - const size_t PKCS8_VERSION = 0; - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(PKCS8_VERSION) - .encode(pkcs8_algorithm_identifier()) - .encode(private_key_bits(), OCTET_STRING) - .end_cons() - .get_contents(); - } - -/* -* Hash of the X.509 subjectPublicKey encoding -*/ -std::string Public_Key::fingerprint_public(const std::string& hash_algo) const - { - return create_hex_fingerprint(subject_public_key(), hash_algo); - } - -/* -* Hash of the PKCS #8 encoding for this key object -*/ -std::string Private_Key::fingerprint_private(const std::string& hash_algo) const - { - return create_hex_fingerprint(private_key_bits(), hash_algo); - } - -std::unique_ptr -Public_Key::create_encryption_op(RandomNumberGenerator& /*rng*/, - const std::string& /*params*/, - const std::string& /*provider*/) const - { - throw Lookup_Error(algo_name() + " does not support encryption"); - } - -std::unique_ptr -Public_Key::create_kem_encryption_op(RandomNumberGenerator& /*rng*/, - const std::string& /*params*/, - const std::string& /*provider*/) const - { - throw Lookup_Error(algo_name() + " does not support KEM encryption"); - } - -std::unique_ptr -Public_Key::create_verification_op(const std::string& /*params*/, - const std::string& /*provider*/) const - { - throw Lookup_Error(algo_name() + " does not support verification"); - } - -std::unique_ptr -Private_Key::create_decryption_op(RandomNumberGenerator& /*rng*/, - const std::string& /*params*/, - const std::string& /*provider*/) const - { - throw Lookup_Error(algo_name() + " does not support decryption"); - } - -std::unique_ptr -Private_Key::create_kem_decryption_op(RandomNumberGenerator& /*rng*/, - const std::string& /*params*/, - const std::string& /*provider*/) const - { - throw Lookup_Error(algo_name() + " does not support KEM decryption"); - } - -std::unique_ptr -Private_Key::create_signature_op(RandomNumberGenerator& /*rng*/, - const std::string& /*params*/, - const std::string& /*provider*/) const - { - throw Lookup_Error(algo_name() + " does not support signatures"); - } - -std::unique_ptr -Private_Key::create_key_agreement_op(RandomNumberGenerator& /*rng*/, - const std::string& /*params*/, - const std::string& /*provider*/) const - { - throw Lookup_Error(algo_name() + " does not support key agreement"); - } + fprint.push_back(hex_hash[i]); + fprint.push_back(hex_hash[i + 1]); + } + return fprint; } -/* -* PK Operation Types -* (C) 2010,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +std::vector Public_Key::subject_public_key() const { + std::vector output; + + DER_Encoder(output) + .start_cons(SEQUENCE) + .encode(algorithm_identifier()) + .encode(public_key_bits(), BIT_STRING) + .end_cons(); + + return output; +} + +/* + * Default OID access + */ +OID Public_Key::get_oid() const { + const OID o = OIDS::str2oid_or_empty(algo_name()); + if (o.empty()) throw Lookup_Error("PK algo " + algo_name() + " has no defined OIDs"); + return o; +} + +secure_vector Private_Key::private_key_info() const { + const size_t PKCS8_VERSION = 0; + + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(PKCS8_VERSION) + .encode(pkcs8_algorithm_identifier()) + .encode(private_key_bits(), OCTET_STRING) + .end_cons() + .get_contents(); +} + +/* + * Hash of the X.509 subjectPublicKey encoding + */ +std::string Public_Key::fingerprint_public(const std::string& hash_algo) const { + return create_hex_fingerprint(subject_public_key(), hash_algo); +} + +/* + * Hash of the PKCS #8 encoding for this key object + */ +std::string Private_Key::fingerprint_private(const std::string& hash_algo) const { + return create_hex_fingerprint(private_key_bits(), hash_algo); +} + +std::unique_ptr Public_Key::create_encryption_op( + RandomNumberGenerator& /*rng*/, const std::string& /*params*/, + const std::string& /*provider*/) const { + throw Lookup_Error(algo_name() + " does not support encryption"); +} + +std::unique_ptr Public_Key::create_kem_encryption_op( + RandomNumberGenerator& /*rng*/, const std::string& /*params*/, + const std::string& /*provider*/) const { + throw Lookup_Error(algo_name() + " does not support KEM encryption"); +} + +std::unique_ptr Public_Key::create_verification_op( + const std::string& /*params*/, const std::string& /*provider*/) const { + throw Lookup_Error(algo_name() + " does not support verification"); +} + +std::unique_ptr Private_Key::create_decryption_op( + RandomNumberGenerator& /*rng*/, const std::string& /*params*/, + const std::string& /*provider*/) const { + throw Lookup_Error(algo_name() + " does not support decryption"); +} + +std::unique_ptr Private_Key::create_kem_decryption_op( + RandomNumberGenerator& /*rng*/, const std::string& /*params*/, + const std::string& /*provider*/) const { + throw Lookup_Error(algo_name() + " does not support KEM decryption"); +} + +std::unique_ptr Private_Key::create_signature_op( + RandomNumberGenerator& /*rng*/, const std::string& /*params*/, + const std::string& /*provider*/) const { + throw Lookup_Error(algo_name() + " does not support signatures"); +} + +std::unique_ptr Private_Key::create_key_agreement_op( + RandomNumberGenerator& /*rng*/, const std::string& /*params*/, + const std::string& /*provider*/) const { + throw Lookup_Error(algo_name() + " does not support key agreement"); +} + +} // namespace Botan +/* + * PK Operation Types + * (C) 2010,2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -PK_Ops::Encryption_with_EME::Encryption_with_EME(const std::string& eme) - { - m_eme.reset(get_eme(eme)); - if(!m_eme.get()) - throw Algorithm_Not_Found(eme); - } +PK_Ops::Encryption_with_EME::Encryption_with_EME(const std::string& eme) { + m_eme.reset(get_eme(eme)); + if (!m_eme.get()) throw Algorithm_Not_Found(eme); +} -size_t PK_Ops::Encryption_with_EME::max_input_bits() const - { - return 8 * m_eme->maximum_input_size(max_raw_input_bits()); - } +size_t PK_Ops::Encryption_with_EME::max_input_bits() const { + return 8 * m_eme->maximum_input_size(max_raw_input_bits()); +} secure_vector PK_Ops::Encryption_with_EME::encrypt(const uint8_t msg[], size_t msg_len, - RandomNumberGenerator& rng) - { - const size_t max_raw = max_raw_input_bits(); - const std::vector encoded = unlock(m_eme->encode(msg, msg_len, max_raw, rng)); - return raw_encrypt(encoded.data(), encoded.size(), rng); - } + RandomNumberGenerator& rng) { + const size_t max_raw = max_raw_input_bits(); + const std::vector encoded = unlock(m_eme->encode(msg, msg_len, max_raw, rng)); + return raw_encrypt(encoded.data(), encoded.size(), rng); +} -PK_Ops::Decryption_with_EME::Decryption_with_EME(const std::string& eme) - { - m_eme.reset(get_eme(eme)); - if(!m_eme.get()) - throw Algorithm_Not_Found(eme); - } +PK_Ops::Decryption_with_EME::Decryption_with_EME(const std::string& eme) { + m_eme.reset(get_eme(eme)); + if (!m_eme.get()) throw Algorithm_Not_Found(eme); +} -secure_vector -PK_Ops::Decryption_with_EME::decrypt(uint8_t& valid_mask, - const uint8_t ciphertext[], - size_t ciphertext_len) - { - const secure_vector raw = raw_decrypt(ciphertext, ciphertext_len); - return m_eme->unpad(valid_mask, raw.data(), raw.size()); - } +secure_vector PK_Ops::Decryption_with_EME::decrypt(uint8_t& valid_mask, + const uint8_t ciphertext[], + size_t ciphertext_len) { + const secure_vector raw = raw_decrypt(ciphertext, ciphertext_len); + return m_eme->unpad(valid_mask, raw.data(), raw.size()); +} -PK_Ops::Key_Agreement_with_KDF::Key_Agreement_with_KDF(const std::string& kdf) - { - if(kdf != "Raw") - m_kdf.reset(get_kdf(kdf)); - } +PK_Ops::Key_Agreement_with_KDF::Key_Agreement_with_KDF(const std::string& kdf) { + if (kdf != "Raw") m_kdf.reset(get_kdf(kdf)); +} -secure_vector PK_Ops::Key_Agreement_with_KDF::agree(size_t key_len, - const uint8_t w[], size_t w_len, - const uint8_t salt[], size_t salt_len) - { - secure_vector z = raw_agree(w, w_len); - if(m_kdf) - return m_kdf->derive_key(key_len, z, salt, salt_len); - return z; - } +secure_vector PK_Ops::Key_Agreement_with_KDF::agree(size_t key_len, const uint8_t w[], + size_t w_len, const uint8_t salt[], + size_t salt_len) { + secure_vector z = raw_agree(w, w_len); + if (m_kdf) return m_kdf->derive_key(key_len, z, salt, salt_len); + return z; +} -PK_Ops::Signature_with_EMSA::Signature_with_EMSA(const std::string& emsa) : - Signature(), - m_emsa(get_emsa(emsa)), - m_hash(hash_for_emsa(emsa)), - m_prefix_used(false) - { - if(!m_emsa) - throw Algorithm_Not_Found(emsa); - } +PK_Ops::Signature_with_EMSA::Signature_with_EMSA(const std::string& emsa) + : Signature(), m_emsa(get_emsa(emsa)), m_hash(hash_for_emsa(emsa)), m_prefix_used(false) { + if (!m_emsa) throw Algorithm_Not_Found(emsa); +} -void PK_Ops::Signature_with_EMSA::update(const uint8_t msg[], size_t msg_len) - { - if(has_prefix() && !m_prefix_used) - { - m_prefix_used = true; - secure_vector prefix = message_prefix(); - m_emsa->update(prefix.data(), prefix.size()); - } - m_emsa->update(msg, msg_len); - } +void PK_Ops::Signature_with_EMSA::update(const uint8_t msg[], size_t msg_len) { + if (has_prefix() && !m_prefix_used) { + m_prefix_used = true; + secure_vector prefix = message_prefix(); + m_emsa->update(prefix.data(), prefix.size()); + } + m_emsa->update(msg, msg_len); +} -secure_vector PK_Ops::Signature_with_EMSA::sign(RandomNumberGenerator& rng) - { - m_prefix_used = false; - const secure_vector msg = m_emsa->raw_data(); - const auto padded = m_emsa->encoding_of(msg, this->max_input_bits(), rng); - return raw_sign(padded.data(), padded.size(), rng); - } +secure_vector PK_Ops::Signature_with_EMSA::sign(RandomNumberGenerator& rng) { + m_prefix_used = false; + const secure_vector msg = m_emsa->raw_data(); + const auto padded = m_emsa->encoding_of(msg, this->max_input_bits(), rng); + return raw_sign(padded.data(), padded.size(), rng); +} -PK_Ops::Verification_with_EMSA::Verification_with_EMSA(const std::string& emsa) : - Verification(), - m_emsa(get_emsa(emsa)), - m_hash(hash_for_emsa(emsa)), - m_prefix_used(false) - { - if(!m_emsa) - throw Algorithm_Not_Found(emsa); - } +PK_Ops::Verification_with_EMSA::Verification_with_EMSA(const std::string& emsa) + : Verification(), m_emsa(get_emsa(emsa)), m_hash(hash_for_emsa(emsa)), m_prefix_used(false) { + if (!m_emsa) throw Algorithm_Not_Found(emsa); +} -void PK_Ops::Verification_with_EMSA::update(const uint8_t msg[], size_t msg_len) - { - if(has_prefix() && !m_prefix_used) - { - m_prefix_used = true; - secure_vector prefix = message_prefix(); - m_emsa->update(prefix.data(), prefix.size()); - } - m_emsa->update(msg, msg_len); - } +void PK_Ops::Verification_with_EMSA::update(const uint8_t msg[], size_t msg_len) { + if (has_prefix() && !m_prefix_used) { + m_prefix_used = true; + secure_vector prefix = message_prefix(); + m_emsa->update(prefix.data(), prefix.size()); + } + m_emsa->update(msg, msg_len); +} -bool PK_Ops::Verification_with_EMSA::is_valid_signature(const uint8_t sig[], size_t sig_len) - { - m_prefix_used = false; - const secure_vector msg = m_emsa->raw_data(); +bool PK_Ops::Verification_with_EMSA::is_valid_signature(const uint8_t sig[], size_t sig_len) { + m_prefix_used = false; + const secure_vector msg = m_emsa->raw_data(); - if(with_recovery()) - { - secure_vector output_of_key = verify_mr(sig, sig_len); - return m_emsa->verify(output_of_key, msg, max_input_bits()); - } - else - { - Null_RNG rng; - secure_vector encoded = m_emsa->encoding_of(msg, max_input_bits(), rng); - return verify(encoded.data(), encoded.size(), sig, sig_len); - } - } + if (with_recovery()) { + secure_vector output_of_key = verify_mr(sig, sig_len); + return m_emsa->verify(output_of_key, msg, max_input_bits()); + } else { + Null_RNG rng; + secure_vector encoded = m_emsa->encoding_of(msg, max_input_bits(), rng); + return verify(encoded.data(), encoded.size(), sig, sig_len); + } +} void PK_Ops::KEM_Encryption_with_KDF::kem_encrypt(secure_vector& out_encapsulated_key, secure_vector& out_shared_key, size_t desired_shared_key_len, Botan::RandomNumberGenerator& rng, - const uint8_t salt[], - size_t salt_len) - { - secure_vector raw_shared; - this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng); - - out_shared_key = m_kdf->derive_key(desired_shared_key_len, - raw_shared.data(), raw_shared.size(), - salt, salt_len); - } - -PK_Ops::KEM_Encryption_with_KDF::KEM_Encryption_with_KDF(const std::string& kdf) - { - m_kdf.reset(get_kdf(kdf)); - } - -secure_vector -PK_Ops::KEM_Decryption_with_KDF::kem_decrypt(const uint8_t encap_key[], - size_t len, - size_t desired_shared_key_len, - const uint8_t salt[], - size_t salt_len) - { - secure_vector raw_shared = this->raw_kem_decrypt(encap_key, len); - - return m_kdf->derive_key(desired_shared_key_len, - raw_shared.data(), raw_shared.size(), - salt, salt_len); - } - -PK_Ops::KEM_Decryption_with_KDF::KEM_Decryption_with_KDF(const std::string& kdf) - { - m_kdf.reset(get_kdf(kdf)); - } + const uint8_t salt[], size_t salt_len) { + secure_vector raw_shared; + this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng); + out_shared_key = m_kdf->derive_key(desired_shared_key_len, raw_shared.data(), raw_shared.size(), + salt, salt_len); } -/* -* PKCS #8 -* (C) 1999-2010,2014,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +PK_Ops::KEM_Encryption_with_KDF::KEM_Encryption_with_KDF(const std::string& kdf) { + m_kdf.reset(get_kdf(kdf)); +} + +secure_vector PK_Ops::KEM_Decryption_with_KDF::kem_decrypt(const uint8_t encap_key[], + size_t len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len) { + secure_vector raw_shared = this->raw_kem_decrypt(encap_key, len); + + return m_kdf->derive_key(desired_shared_key_len, raw_shared.data(), raw_shared.size(), salt, + salt_len); +} + +PK_Ops::KEM_Decryption_with_KDF::KEM_Decryption_with_KDF(const std::string& kdf) { + m_kdf.reset(get_kdf(kdf)); +} + +} // namespace Botan +/* + * PKCS #8 + * (C) 1999-2010,2014,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_PKCS5_PBES2) #endif @@ -22642,1479 +20416,1252 @@ namespace PKCS8 { namespace { /* -* Get info from an EncryptedPrivateKeyInfo -*/ -secure_vector PKCS8_extract(DataSource& source, - AlgorithmIdentifier& pbe_alg_id) - { - secure_vector key_data; + * Get info from an EncryptedPrivateKeyInfo + */ +secure_vector PKCS8_extract(DataSource& source, AlgorithmIdentifier& pbe_alg_id) { + secure_vector key_data; - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(pbe_alg_id) - .decode(key_data, OCTET_STRING) - .verify_end(); + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(pbe_alg_id) + .decode(key_data, OCTET_STRING) + .verify_end(); - return key_data; - } + return key_data; +} /* -* PEM decode and/or decrypt a private key -*/ -secure_vector PKCS8_decode( - DataSource& source, - std::function get_passphrase, - AlgorithmIdentifier& pk_alg_id, - bool is_encrypted) - { - AlgorithmIdentifier pbe_alg_id; - secure_vector key_data, key; + * PEM decode and/or decrypt a private key + */ +secure_vector PKCS8_decode(DataSource& source, std::function get_passphrase, + AlgorithmIdentifier& pk_alg_id, bool is_encrypted) { + AlgorithmIdentifier pbe_alg_id; + secure_vector key_data, key; - try { - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - { - if(is_encrypted) - { - key_data = PKCS8_extract(source, pbe_alg_id); + try { + if (ASN1::maybe_BER(source) && !PEM_Code::matches(source)) { + if (is_encrypted) { + key_data = PKCS8_extract(source, pbe_alg_id); + } else { + // todo read more efficiently + while (!source.end_of_data()) { + uint8_t b; + size_t read = source.read_byte(b); + if (read) { + key_data.push_back(b); + } + } } - else - { - // todo read more efficiently - while(!source.end_of_data()) - { - uint8_t b; - size_t read = source.read_byte(b); - if(read) - { - key_data.push_back(b); - } - } - } - } - else - { - std::string label; - key_data = PEM_Code::decode(source, label); + } else { + std::string label; + key_data = PEM_Code::decode(source, label); - // todo remove autodetect for pem as well? - if(label == "PRIVATE KEY") - is_encrypted = false; - else if(label == "ENCRYPTED PRIVATE KEY") - { - DataSource_Memory key_source(key_data); - key_data = PKCS8_extract(key_source, pbe_alg_id); - } - else - throw PKCS8_Exception("Unknown PEM label " + label); - } + // todo remove autodetect for pem as well? + if (label == "PRIVATE KEY") + is_encrypted = false; + else if (label == "ENCRYPTED PRIVATE KEY") { + DataSource_Memory key_source(key_data); + key_data = PKCS8_extract(key_source, pbe_alg_id); + } else + throw PKCS8_Exception("Unknown PEM label " + label); + } - if(key_data.empty()) - throw PKCS8_Exception("No key data found"); - } - catch(Decoding_Error& e) - { - throw Decoding_Error("PKCS #8 private key decoding", e); - } + if (key_data.empty()) throw PKCS8_Exception("No key data found"); + } catch (Decoding_Error& e) { + throw Decoding_Error("PKCS #8 private key decoding", e); + } - try - { - if(is_encrypted) - { - if(OIDS::oid2str_or_throw(pbe_alg_id.get_oid()) != "PBE-PKCS5v20") - throw PKCS8_Exception("Unknown PBE type " + pbe_alg_id.get_oid().to_string()); + try { + if (is_encrypted) { + if (OIDS::oid2str_or_throw(pbe_alg_id.get_oid()) != "PBE-PKCS5v20") + throw PKCS8_Exception("Unknown PBE type " + pbe_alg_id.get_oid().to_string()); #if defined(BOTAN_HAS_PKCS5_PBES2) - key = pbes2_decrypt(key_data, get_passphrase(), pbe_alg_id.get_parameters()); + key = pbes2_decrypt(key_data, get_passphrase(), pbe_alg_id.get_parameters()); #else - BOTAN_UNUSED(get_passphrase); - throw Decoding_Error("Private key is encrypted but PBES2 was disabled in build"); + BOTAN_UNUSED(get_passphrase); + throw Decoding_Error("Private key is encrypted but PBES2 was disabled in build"); #endif - } - else - key = key_data; + } else + key = key_data; - BER_Decoder(key) - .start_cons(SEQUENCE) + BER_Decoder(key) + .start_cons(SEQUENCE) .decode_and_check(0, "Unknown PKCS #8 version number") .decode(pk_alg_id) .decode(key, OCTET_STRING) .discard_remaining() - .end_cons(); - } - catch(std::exception& e) - { - throw Decoding_Error("PKCS #8 private key decoding", e); - } - return key; - } + .end_cons(); + } catch (std::exception& e) { + throw Decoding_Error("PKCS #8 private key decoding", e); + } + return key; +} +} // namespace + +/* + * BER encode a PKCS #8 private key, unencrypted + */ +secure_vector BER_encode(const Private_Key& key) { + // keeping around for compat + return key.private_key_info(); } /* -* BER encode a PKCS #8 private key, unencrypted -*/ -secure_vector BER_encode(const Private_Key& key) - { - // keeping around for compat - return key.private_key_info(); - } - -/* -* PEM encode a PKCS #8 private key, unencrypted -*/ -std::string PEM_encode(const Private_Key& key) - { - return PEM_Code::encode(PKCS8::BER_encode(key), "PRIVATE KEY"); - } + * PEM encode a PKCS #8 private key, unencrypted + */ +std::string PEM_encode(const Private_Key& key) { + return PEM_Code::encode(PKCS8::BER_encode(key), "PRIVATE KEY"); +} #if defined(BOTAN_HAS_PKCS5_PBES2) namespace { -std::pair -choose_pbe_params(const std::string& pbe_algo, const std::string& key_algo) - { - if(pbe_algo.empty()) - { - /* - * For algorithms where we are using a non-RFC format anyway, default to - * SIV or GCM. For others (RSA, ECDSA, ...) default to something widely - * compatible. - */ - const bool nonstandard_pk = (key_algo == "McEliece" || key_algo == "XMSS"); +std::pair choose_pbe_params(const std::string& pbe_algo, + const std::string& key_algo) { + if (pbe_algo.empty()) { + /* + * For algorithms where we are using a non-RFC format anyway, default to + * SIV or GCM. For others (RSA, ECDSA, ...) default to something widely + * compatible. + */ + const bool nonstandard_pk = (key_algo == "McEliece" || key_algo == "XMSS"); - if(nonstandard_pk) - { + if (nonstandard_pk) { #if defined(BOTAN_HAS_AEAD_SIV) && defined(BOTAN_HAS_SHA2_64) - return std::make_pair("AES-256/SIV", "SHA-512"); + return std::make_pair("AES-256/SIV", "SHA-512"); #elif defined(BOTAN_HAS_AEAD_GCM) && defined(BOTAN_HAS_SHA2_64) - return std::make_pair("AES-256/GCM", "SHA-512"); + return std::make_pair("AES-256/GCM", "SHA-512"); #endif - } + } - // Default is something compatible with everyone else - return std::make_pair("AES-256/CBC", "SHA-256"); - } + // Default is something compatible with everyone else + return std::make_pair("AES-256/CBC", "SHA-256"); + } - SCAN_Name request(pbe_algo); + SCAN_Name request(pbe_algo); - if(request.arg_count() != 2 || - (request.algo_name() != "PBE-PKCS5v20" && request.algo_name() != "PBES2")) - { - throw Invalid_Argument("Unsupported PBE " + pbe_algo); - } - - return std::make_pair(request.arg(0), request.arg(1)); - } + if (request.arg_count() != 2 || + (request.algo_name() != "PBE-PKCS5v20" && request.algo_name() != "PBES2")) { + throw Invalid_Argument("Unsupported PBE " + pbe_algo); + } + return std::make_pair(request.arg(0), request.arg(1)); } +} // namespace + #endif /* -* BER encode a PKCS #8 private key, encrypted -*/ -std::vector BER_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - std::chrono::milliseconds msec, - const std::string& pbe_algo) - { + * BER encode a PKCS #8 private key, encrypted + */ +std::vector BER_encode(const Private_Key& key, RandomNumberGenerator& rng, + const std::string& pass, std::chrono::milliseconds msec, + const std::string& pbe_algo) { #if defined(BOTAN_HAS_PKCS5_PBES2) - const auto pbe_params = choose_pbe_params(pbe_algo, key.algo_name()); + const auto pbe_params = choose_pbe_params(pbe_algo, key.algo_name()); - const std::pair> pbe_info = - pbes2_encrypt_msec(PKCS8::BER_encode(key), pass, msec, nullptr, - pbe_params.first, pbe_params.second, rng); + const std::pair> pbe_info = pbes2_encrypt_msec( + PKCS8::BER_encode(key), pass, msec, nullptr, pbe_params.first, pbe_params.second, rng); - std::vector output; - DER_Encoder der(output); - der.start_cons(SEQUENCE) - .encode(pbe_info.first) - .encode(pbe_info.second, OCTET_STRING) - .end_cons(); + std::vector output; + DER_Encoder der(output); + der.start_cons(SEQUENCE) + .encode(pbe_info.first) + .encode(pbe_info.second, OCTET_STRING) + .end_cons(); - return output; + return output; #else - BOTAN_UNUSED(key, rng, pass, msec, pbe_algo); - throw Encoding_Error("PKCS8::BER_encode cannot encrypt because PBES2 was disabled in build"); + BOTAN_UNUSED(key, rng, pass, msec, pbe_algo); + throw Encoding_Error("PKCS8::BER_encode cannot encrypt because PBES2 was disabled in build"); #endif - } +} /* -* PEM encode a PKCS #8 private key, encrypted -*/ -std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - std::chrono::milliseconds msec, - const std::string& pbe_algo) - { - if(pass.empty()) - return PEM_encode(key); + * PEM encode a PKCS #8 private key, encrypted + */ +std::string PEM_encode(const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, + std::chrono::milliseconds msec, const std::string& pbe_algo) { + if (pass.empty()) return PEM_encode(key); - return PEM_Code::encode(PKCS8::BER_encode(key, rng, pass, msec, pbe_algo), - "ENCRYPTED PRIVATE KEY"); - } + return PEM_Code::encode(PKCS8::BER_encode(key, rng, pass, msec, pbe_algo), + "ENCRYPTED PRIVATE KEY"); +} /* -* BER encode a PKCS #8 private key, encrypted -*/ -std::vector BER_encode_encrypted_pbkdf_iter(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - size_t pbkdf_iterations, - const std::string& cipher, - const std::string& pbkdf_hash) - { + * BER encode a PKCS #8 private key, encrypted + */ +std::vector BER_encode_encrypted_pbkdf_iter( + const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, + size_t pbkdf_iterations, const std::string& cipher, const std::string& pbkdf_hash) { #if defined(BOTAN_HAS_PKCS5_PBES2) - const std::pair> pbe_info = - pbes2_encrypt_iter(key.private_key_info(), - pass, pbkdf_iterations, - cipher.empty() ? "AES-256/CBC" : cipher, - pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash, - rng); + const std::pair> pbe_info = pbes2_encrypt_iter( + key.private_key_info(), pass, pbkdf_iterations, cipher.empty() ? "AES-256/CBC" : cipher, + pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash, rng); - std::vector output; - DER_Encoder der(output); - der.start_cons(SEQUENCE) - .encode(pbe_info.first) - .encode(pbe_info.second, OCTET_STRING) - .end_cons(); + std::vector output; + DER_Encoder der(output); + der.start_cons(SEQUENCE) + .encode(pbe_info.first) + .encode(pbe_info.second, OCTET_STRING) + .end_cons(); - return output; + return output; #else - BOTAN_UNUSED(key, rng, pass, pbkdf_iterations, cipher, pbkdf_hash); - throw Encoding_Error("PKCS8::BER_encode_encrypted_pbkdf_iter cannot encrypt because PBES2 disabled in build"); + BOTAN_UNUSED(key, rng, pass, pbkdf_iterations, cipher, pbkdf_hash); + throw Encoding_Error( + "PKCS8::BER_encode_encrypted_pbkdf_iter cannot encrypt because PBES2 disabled in build"); #endif - } +} /* -* PEM encode a PKCS #8 private key, encrypted -*/ -std::string PEM_encode_encrypted_pbkdf_iter(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - size_t pbkdf_iterations, + * PEM encode a PKCS #8 private key, encrypted + */ +std::string PEM_encode_encrypted_pbkdf_iter(const Private_Key& key, RandomNumberGenerator& rng, + const std::string& pass, size_t pbkdf_iterations, const std::string& cipher, - const std::string& pbkdf_hash) - { - return PEM_Code::encode( - PKCS8::BER_encode_encrypted_pbkdf_iter(key, rng, pass, pbkdf_iterations, cipher, pbkdf_hash), - "ENCRYPTED PRIVATE KEY"); - } + const std::string& pbkdf_hash) { + return PEM_Code::encode(PKCS8::BER_encode_encrypted_pbkdf_iter(key, rng, pass, pbkdf_iterations, + cipher, pbkdf_hash), + "ENCRYPTED PRIVATE KEY"); +} /* -* BER encode a PKCS #8 private key, encrypted -*/ -std::vector BER_encode_encrypted_pbkdf_msec(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - std::chrono::milliseconds pbkdf_msec, - size_t* pbkdf_iterations, - const std::string& cipher, - const std::string& pbkdf_hash) - { + * BER encode a PKCS #8 private key, encrypted + */ +std::vector BER_encode_encrypted_pbkdf_msec( + const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, + std::chrono::milliseconds pbkdf_msec, size_t* pbkdf_iterations, const std::string& cipher, + const std::string& pbkdf_hash) { #if defined(BOTAN_HAS_PKCS5_PBES2) - const std::pair> pbe_info = - pbes2_encrypt_msec(key.private_key_info(), pass, - pbkdf_msec, pbkdf_iterations, - cipher.empty() ? "AES-256/CBC" : cipher, - pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash, - rng); + const std::pair> pbe_info = pbes2_encrypt_msec( + key.private_key_info(), pass, pbkdf_msec, pbkdf_iterations, + cipher.empty() ? "AES-256/CBC" : cipher, pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash, rng); - std::vector output; - DER_Encoder(output) - .start_cons(SEQUENCE) - .encode(pbe_info.first) - .encode(pbe_info.second, OCTET_STRING) - .end_cons(); + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .encode(pbe_info.first) + .encode(pbe_info.second, OCTET_STRING) + .end_cons(); - return output; + return output; #else - BOTAN_UNUSED(key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash); - throw Encoding_Error("BER_encode_encrypted_pbkdf_msec cannot encrypt because PBES2 disabled in build"); + BOTAN_UNUSED(key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash); + throw Encoding_Error( + "BER_encode_encrypted_pbkdf_msec cannot encrypt because PBES2 disabled in build"); #endif - } +} /* -* PEM encode a PKCS #8 private key, encrypted -*/ -std::string PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, - RandomNumberGenerator& rng, + * PEM encode a PKCS #8 private key, encrypted + */ +std::string PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, std::chrono::milliseconds pbkdf_msec, - size_t* pbkdf_iterations, - const std::string& cipher, - const std::string& pbkdf_hash) - { - return PEM_Code::encode( - PKCS8::BER_encode_encrypted_pbkdf_msec(key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash), - "ENCRYPTED PRIVATE KEY"); - } + size_t* pbkdf_iterations, const std::string& cipher, + const std::string& pbkdf_hash) { + return PEM_Code::encode(PKCS8::BER_encode_encrypted_pbkdf_msec( + key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash), + "ENCRYPTED PRIVATE KEY"); +} namespace { /* -* Extract a private key (encrypted/unencrypted) and return it -*/ -std::unique_ptr -load_key(DataSource& source, - std::function get_pass, - bool is_encrypted) - { - AlgorithmIdentifier alg_id; - secure_vector pkcs8_key = PKCS8_decode(source, get_pass, alg_id, is_encrypted); + * Extract a private key (encrypted/unencrypted) and return it + */ +std::unique_ptr load_key(DataSource& source, std::function get_pass, + bool is_encrypted) { + AlgorithmIdentifier alg_id; + secure_vector pkcs8_key = PKCS8_decode(source, get_pass, alg_id, is_encrypted); - const std::string alg_name = OIDS::oid2str_or_empty(alg_id.get_oid()); - if(alg_name.empty()) - throw PKCS8_Exception("Unknown algorithm OID: " + - alg_id.get_oid().to_string()); + const std::string alg_name = OIDS::oid2str_or_empty(alg_id.get_oid()); + if (alg_name.empty()) + throw PKCS8_Exception("Unknown algorithm OID: " + alg_id.get_oid().to_string()); - return load_private_key(alg_id, pkcs8_key); - } + return load_private_key(alg_id, pkcs8_key); +} +} // namespace + +/* + * Extract an encrypted private key and return it + */ +std::unique_ptr load_key(DataSource& source, std::function get_pass) { + return load_key(source, get_pass, true); } /* -* Extract an encrypted private key and return it -*/ -std::unique_ptr load_key(DataSource& source, - std::function get_pass) - { - return load_key(source, get_pass, true); - } + * Extract an encrypted private key and return it + */ +std::unique_ptr load_key(DataSource& source, const std::string& pass) { + return load_key(source, [pass]() { return pass; }, true); +} /* -* Extract an encrypted private key and return it -*/ -std::unique_ptr load_key(DataSource& source, - const std::string& pass) - { - return load_key(source, [pass]() { return pass; }, true); - } + * Extract an unencrypted private key and return it + */ +std::unique_ptr load_key(DataSource& source) { + auto fail_fn = []() -> std::string { + throw PKCS8_Exception("Internal error: Attempt to read password for unencrypted key"); + }; + + return load_key(source, fail_fn, false); +} /* -* Extract an unencrypted private key and return it -*/ -std::unique_ptr load_key(DataSource& source) - { - auto fail_fn = []() -> std::string { - throw PKCS8_Exception("Internal error: Attempt to read password for unencrypted key"); - }; - - return load_key(source, fail_fn, false); - } + * Make a copy of this private key + */ +std::unique_ptr copy_key(const Private_Key& key) { + DataSource_Memory source(PEM_encode(key)); + return PKCS8::load_key(source); +} /* -* Make a copy of this private key -*/ -std::unique_ptr copy_key(const Private_Key& key) - { - DataSource_Memory source(PEM_encode(key)); - return PKCS8::load_key(source); - } + * Extract an encrypted private key and return it + */ +Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng, + std::function get_pass) { + BOTAN_UNUSED(rng); + return PKCS8::load_key(source, get_pass).release(); +} /* -* Extract an encrypted private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - std::function get_pass) - { - BOTAN_UNUSED(rng); - return PKCS8::load_key(source, get_pass).release(); - } + * Extract an encrypted private key and return it + */ +Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng, const std::string& pass) { + BOTAN_UNUSED(rng); + return PKCS8::load_key(source, pass).release(); +} /* -* Extract an encrypted private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass) - { - BOTAN_UNUSED(rng); - return PKCS8::load_key(source, pass).release(); - } - -/* -* Extract an unencrypted private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng) - { - BOTAN_UNUSED(rng); - return PKCS8::load_key(source).release(); - } + * Extract an unencrypted private key and return it + */ +Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng) { + BOTAN_UNUSED(rng); + return PKCS8::load_key(source).release(); +} #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) /* -* Extract an encrypted private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - std::function get_pass) - { - BOTAN_UNUSED(rng); - DataSource_Stream in(fsname); - return PKCS8::load_key(in, get_pass).release(); - } + * Extract an encrypted private key and return it + */ +Private_Key* load_key(const std::string& fsname, RandomNumberGenerator& rng, + std::function get_pass) { + BOTAN_UNUSED(rng); + DataSource_Stream in(fsname); + return PKCS8::load_key(in, get_pass).release(); +} /* -* Extract an encrypted private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const std::string& pass) - { - BOTAN_UNUSED(rng); - DataSource_Stream in(fsname); - return PKCS8::load_key(in, [pass]() { return pass; }).release(); - } + * Extract an encrypted private key and return it + */ +Private_Key* load_key(const std::string& fsname, RandomNumberGenerator& rng, + const std::string& pass) { + BOTAN_UNUSED(rng); + DataSource_Stream in(fsname); + return PKCS8::load_key(in, [pass]() { return pass; }).release(); +} /* -* Extract an unencrypted private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng) - { - BOTAN_UNUSED(rng); - DataSource_Stream in(fsname); - return PKCS8::load_key(in).release(); - } + * Extract an unencrypted private key and return it + */ +Private_Key* load_key(const std::string& fsname, RandomNumberGenerator& rng) { + BOTAN_UNUSED(rng); + DataSource_Stream in(fsname); + return PKCS8::load_key(in).release(); +} #endif /* -* Make a copy of this private key -*/ -Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng) - { - BOTAN_UNUSED(rng); - return PKCS8::copy_key(key).release(); - } - - - + * Make a copy of this private key + */ +Private_Key* copy_key(const Private_Key& key, RandomNumberGenerator& rng) { + BOTAN_UNUSED(rng); + return PKCS8::copy_key(key).release(); } -} +} // namespace PKCS8 + +} // namespace Botan /* -* (C) 1999-2010,2015,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * (C) 1999-2010,2015,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -secure_vector PK_Decryptor::decrypt(const uint8_t in[], size_t length) const - { - uint8_t valid_mask = 0; +secure_vector PK_Decryptor::decrypt(const uint8_t in[], size_t length) const { + uint8_t valid_mask = 0; - secure_vector decoded = do_decrypt(valid_mask, in, length); + secure_vector decoded = do_decrypt(valid_mask, in, length); - if(valid_mask == 0) - throw Decoding_Error("Invalid public key ciphertext, cannot decrypt"); + if (valid_mask == 0) throw Decoding_Error("Invalid public key ciphertext, cannot decrypt"); - return decoded; - } + return decoded; +} -secure_vector -PK_Decryptor::decrypt_or_random(const uint8_t in[], - size_t length, - size_t expected_pt_len, - RandomNumberGenerator& rng, - const uint8_t required_content_bytes[], - const uint8_t required_content_offsets[], - size_t required_contents_length) const - { - const secure_vector fake_pms = rng.random_vec(expected_pt_len); +secure_vector PK_Decryptor::decrypt_or_random(const uint8_t in[], size_t length, + size_t expected_pt_len, + RandomNumberGenerator& rng, + const uint8_t required_content_bytes[], + const uint8_t required_content_offsets[], + size_t required_contents_length) const { + const secure_vector fake_pms = rng.random_vec(expected_pt_len); - uint8_t decrypt_valid = 0; - secure_vector decoded = do_decrypt(decrypt_valid, in, length); + uint8_t decrypt_valid = 0; + secure_vector decoded = do_decrypt(decrypt_valid, in, length); - auto valid_mask = CT::Mask::is_equal(decrypt_valid, 0xFF); - valid_mask &= CT::Mask(CT::Mask::is_zero(decoded.size() ^ expected_pt_len)); + auto valid_mask = CT::Mask::is_equal(decrypt_valid, 0xFF); + valid_mask &= CT::Mask(CT::Mask::is_zero(decoded.size() ^ expected_pt_len)); - decoded.resize(expected_pt_len); + decoded.resize(expected_pt_len); - for(size_t i = 0; i != required_contents_length; ++i) - { - /* - These values are chosen by the application and for TLS are constants, - so this early failure via assert is fine since we know 0,1 < 48 + for (size_t i = 0; i != required_contents_length; ++i) { + /* + These values are chosen by the application and for TLS are constants, + so this early failure via assert is fine since we know 0,1 < 48 - If there is a protocol that has content checks on the key where - the expected offsets are controllable by the attacker this could - still leak. + If there is a protocol that has content checks on the key where + the expected offsets are controllable by the attacker this could + still leak. - Alternately could always reduce the offset modulo the length? - */ + Alternately could always reduce the offset modulo the length? + */ - const uint8_t exp = required_content_bytes[i]; - const uint8_t off = required_content_offsets[i]; + const uint8_t exp = required_content_bytes[i]; + const uint8_t off = required_content_offsets[i]; - BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext"); + BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext"); - auto eq = CT::Mask::is_equal(decoded[off], exp); + auto eq = CT::Mask::is_equal(decoded[off], exp); - valid_mask &= eq; - } + valid_mask &= eq; + } - // If valid_mask is false, assign fake pre master instead - valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len); + // If valid_mask is false, assign fake pre master instead + valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len); - return decoded; - } + return decoded; +} -secure_vector -PK_Decryptor::decrypt_or_random(const uint8_t in[], - size_t length, - size_t expected_pt_len, - RandomNumberGenerator& rng) const - { - return decrypt_or_random(in, length, expected_pt_len, rng, - nullptr, nullptr, 0); - } +secure_vector PK_Decryptor::decrypt_or_random(const uint8_t in[], size_t length, + size_t expected_pt_len, + RandomNumberGenerator& rng) const { + return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0); +} -PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, - RandomNumberGenerator& rng, - const std::string& padding, - const std::string& provider) - { - m_op = key.create_encryption_op(rng, padding, provider); - if(!m_op) - throw Invalid_Argument("Key type " + key.algo_name() + " does not support encryption"); - } +PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, RandomNumberGenerator& rng, + const std::string& padding, const std::string& provider) { + m_op = key.create_encryption_op(rng, padding, provider); + if (!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support encryption"); +} PK_Encryptor_EME::~PK_Encryptor_EME() { /* for unique_ptr */ } -size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const - { - return m_op->ciphertext_length(ptext_len); - } +size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const { + return m_op->ciphertext_length(ptext_len); +} -std::vector -PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const - { - return unlock(m_op->encrypt(in, length, rng)); - } +std::vector PK_Encryptor_EME::enc(const uint8_t in[], size_t length, + RandomNumberGenerator& rng) const { + return unlock(m_op->encrypt(in, length, rng)); +} -size_t PK_Encryptor_EME::maximum_input_size() const - { - return m_op->max_input_bits() / 8; - } +size_t PK_Encryptor_EME::maximum_input_size() const { return m_op->max_input_bits() / 8; } -PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& padding, - const std::string& provider) - { - m_op = key.create_decryption_op(rng, padding, provider); - if(!m_op) - throw Invalid_Argument("Key type " + key.algo_name() + " does not support decryption"); - } +PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, RandomNumberGenerator& rng, + const std::string& padding, const std::string& provider) { + m_op = key.create_decryption_op(rng, padding, provider); + if (!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support decryption"); +} PK_Decryptor_EME::~PK_Decryptor_EME() { /* for unique_ptr */ } -size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const - { - return m_op->plaintext_length(ctext_len); - } +size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const { + return m_op->plaintext_length(ctext_len); +} -secure_vector PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, - const uint8_t in[], size_t in_len) const - { - return m_op->decrypt(valid_mask, in, in_len); - } +secure_vector PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], + size_t in_len) const { + return m_op->decrypt(valid_mask, in, in_len); +} -PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, - RandomNumberGenerator& rng, - const std::string& param, - const std::string& provider) - { - m_op = key.create_kem_encryption_op(rng, param, provider); - if(!m_op) - throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM encryption"); - } +PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, RandomNumberGenerator& rng, + const std::string& param, const std::string& provider) { + m_op = key.create_kem_encryption_op(rng, param, provider); + if (!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM encryption"); +} PK_KEM_Encryptor::~PK_KEM_Encryptor() { /* for unique_ptr */ } void PK_KEM_Encryptor::encrypt(secure_vector& out_encapsulated_key, secure_vector& out_shared_key, - size_t desired_shared_key_len, - Botan::RandomNumberGenerator& rng, - const uint8_t salt[], - size_t salt_len) - { - m_op->kem_encrypt(out_encapsulated_key, - out_shared_key, - desired_shared_key_len, - rng, - salt, - salt_len); - } + size_t desired_shared_key_len, Botan::RandomNumberGenerator& rng, + const uint8_t salt[], size_t salt_len) { + m_op->kem_encrypt(out_encapsulated_key, out_shared_key, desired_shared_key_len, rng, salt, + salt_len); +} -PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& param, - const std::string& provider) - { - m_op = key.create_kem_decryption_op(rng, param, provider); - if(!m_op) - throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM decryption"); - } +PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key, RandomNumberGenerator& rng, + const std::string& param, const std::string& provider) { + m_op = key.create_kem_decryption_op(rng, param, provider); + if (!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM decryption"); +} PK_KEM_Decryptor::~PK_KEM_Decryptor() { /* for unique_ptr */ } -secure_vector PK_KEM_Decryptor::decrypt(const uint8_t encap_key[], - size_t encap_key_len, - size_t desired_shared_key_len, - const uint8_t salt[], - size_t salt_len) - { - return m_op->kem_decrypt(encap_key, encap_key_len, - desired_shared_key_len, - salt, salt_len); - } +secure_vector PK_KEM_Decryptor::decrypt(const uint8_t encap_key[], size_t encap_key_len, + size_t desired_shared_key_len, + const uint8_t salt[], size_t salt_len) { + return m_op->kem_decrypt(encap_key, encap_key_len, desired_shared_key_len, salt, salt_len); +} -PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& kdf, - const std::string& provider) - { - m_op = key.create_key_agreement_op(rng, kdf, provider); - if(!m_op) - throw Invalid_Argument("Key type " + key.algo_name() + " does not support key agreement"); - } +PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key, RandomNumberGenerator& rng, + const std::string& kdf, const std::string& provider) { + m_op = key.create_key_agreement_op(rng, kdf, provider); + if (!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support key agreement"); +} PK_Key_Agreement::~PK_Key_Agreement() { /* for unique_ptr */ } -PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&& other) - { - if(this != &other) - { - m_op = std::move(other.m_op); - } - return (*this); - } +PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&& other) { + if (this != &other) { + m_op = std::move(other.m_op); + } + return (*this); +} -PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&& other) : - m_op(std::move(other.m_op)) - {} +PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&& other) : m_op(std::move(other.m_op)) {} -size_t PK_Key_Agreement::agreed_value_size() const - { - return m_op->agreed_value_size(); - } +size_t PK_Key_Agreement::agreed_value_size() const { return m_op->agreed_value_size(); } -SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, - const uint8_t in[], size_t in_len, - const uint8_t salt[], - size_t salt_len) const - { - return m_op->agree(key_len, in, in_len, salt, salt_len); - } +SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, const uint8_t in[], size_t in_len, + const uint8_t salt[], size_t salt_len) const { + return m_op->agree(key_len, in, in_len, salt, salt_len); +} -PK_Signer::PK_Signer(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& emsa, - Signature_Format format, - const std::string& provider) - { - m_op = key.create_signature_op(rng, emsa, provider); - if(!m_op) - throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature generation"); - m_sig_format = format; - m_parts = key.message_parts(); - m_part_size = key.message_part_size(); - } +PK_Signer::PK_Signer(const Private_Key& key, RandomNumberGenerator& rng, const std::string& emsa, + Signature_Format format, const std::string& provider) { + m_op = key.create_signature_op(rng, emsa, provider); + if (!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + + " does not support signature generation"); + m_sig_format = format; + m_parts = key.message_parts(); + m_part_size = key.message_part_size(); +} PK_Signer::~PK_Signer() { /* for unique_ptr */ } -void PK_Signer::update(const uint8_t in[], size_t length) - { - m_op->update(in, length); - } +void PK_Signer::update(const uint8_t in[], size_t length) { m_op->update(in, length); } namespace { -std::vector der_encode_signature(const std::vector& sig, - size_t parts, - size_t part_size) - { - if(sig.size() % parts != 0 || sig.size() != parts * part_size) - throw Encoding_Error("Unexpected size for DER signature"); +std::vector der_encode_signature(const std::vector& sig, size_t parts, + size_t part_size) { + if (sig.size() % parts != 0 || sig.size() != parts * part_size) + throw Encoding_Error("Unexpected size for DER signature"); - std::vector sig_parts(parts); - for(size_t i = 0; i != sig_parts.size(); ++i) - sig_parts[i].binary_decode(&sig[part_size*i], part_size); - - std::vector output; - DER_Encoder(output) - .start_cons(SEQUENCE) - .encode_list(sig_parts) - .end_cons(); - return output; - } + std::vector sig_parts(parts); + for (size_t i = 0; i != sig_parts.size(); ++i) + sig_parts[i].binary_decode(&sig[part_size * i], part_size); + std::vector output; + DER_Encoder(output).start_cons(SEQUENCE).encode_list(sig_parts).end_cons(); + return output; } -size_t PK_Signer::signature_length() const - { - if(m_sig_format == IEEE_1363) - { - return m_op->signature_length(); - } - else if(m_sig_format == DER_SEQUENCE) - { - // This is a large over-estimate but its easier than computing - // the exact value - return m_op->signature_length() + (8 + 4*m_parts); - } - else - throw Internal_Error("PK_Signer: Invalid signature format enum"); - } +} // namespace -std::vector PK_Signer::signature(RandomNumberGenerator& rng) - { - const std::vector sig = unlock(m_op->sign(rng)); +size_t PK_Signer::signature_length() const { + if (m_sig_format == IEEE_1363) { + return m_op->signature_length(); + } else if (m_sig_format == DER_SEQUENCE) { + // This is a large over-estimate but its easier than computing + // the exact value + return m_op->signature_length() + (8 + 4 * m_parts); + } else + throw Internal_Error("PK_Signer: Invalid signature format enum"); +} - if(m_sig_format == IEEE_1363) - { - return sig; - } - else if(m_sig_format == DER_SEQUENCE) - { - return der_encode_signature(sig, m_parts, m_part_size); - } - else - throw Internal_Error("PK_Signer: Invalid signature format enum"); - } +std::vector PK_Signer::signature(RandomNumberGenerator& rng) { + const std::vector sig = unlock(m_op->sign(rng)); -PK_Verifier::PK_Verifier(const Public_Key& key, - const std::string& emsa, - Signature_Format format, - const std::string& provider) - { - m_op = key.create_verification_op(emsa, provider); - if(!m_op) - throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature verification"); - m_sig_format = format; - m_parts = key.message_parts(); - m_part_size = key.message_part_size(); - } + if (m_sig_format == IEEE_1363) { + return sig; + } else if (m_sig_format == DER_SEQUENCE) { + return der_encode_signature(sig, m_parts, m_part_size); + } else + throw Internal_Error("PK_Signer: Invalid signature format enum"); +} + +PK_Verifier::PK_Verifier(const Public_Key& key, const std::string& emsa, Signature_Format format, + const std::string& provider) { + m_op = key.create_verification_op(emsa, provider); + if (!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + + " does not support signature verification"); + m_sig_format = format; + m_parts = key.message_parts(); + m_part_size = key.message_part_size(); +} PK_Verifier::~PK_Verifier() { /* for unique_ptr */ } -void PK_Verifier::set_input_format(Signature_Format format) - { - if(format != IEEE_1363 && m_parts == 1) - throw Invalid_Argument("PK_Verifier: This algorithm does not support DER encoding"); - m_sig_format = format; - } - -bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, - const uint8_t sig[], size_t sig_length) - { - update(msg, msg_length); - return check_signature(sig, sig_length); - } - -void PK_Verifier::update(const uint8_t in[], size_t length) - { - m_op->update(in, length); - } - -bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) - { - try { - if(m_sig_format == IEEE_1363) - { - return m_op->is_valid_signature(sig, length); - } - else if(m_sig_format == DER_SEQUENCE) - { - std::vector real_sig; - BER_Decoder decoder(sig, length); - BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); - - BOTAN_ASSERT_NOMSG(m_parts != 0 && m_part_size != 0); - - size_t count = 0; - - while(ber_sig.more_items()) - { - BigInt sig_part; - ber_sig.decode(sig_part); - real_sig += BigInt::encode_1363(sig_part, m_part_size); - ++count; - } - - if(count != m_parts) - throw Decoding_Error("PK_Verifier: signature size invalid"); - - const std::vector reencoded = - der_encode_signature(real_sig, m_parts, m_part_size); - - if(reencoded.size() != length || - same_mem(reencoded.data(), sig, reencoded.size()) == false) - { - throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding"); - } - - return m_op->is_valid_signature(real_sig.data(), real_sig.size()); - } - else - throw Internal_Error("PK_Verifier: Invalid signature format enum"); - } - catch(Invalid_Argument&) { return false; } - } - +void PK_Verifier::set_input_format(Signature_Format format) { + if (format != IEEE_1363 && m_parts == 1) + throw Invalid_Argument("PK_Verifier: This algorithm does not support DER encoding"); + m_sig_format = format; } + +bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], + size_t sig_length) { + update(msg, msg_length); + return check_signature(sig, sig_length); +} + +void PK_Verifier::update(const uint8_t in[], size_t length) { m_op->update(in, length); } + +bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) { + try { + if (m_sig_format == IEEE_1363) { + return m_op->is_valid_signature(sig, length); + } else if (m_sig_format == DER_SEQUENCE) { + std::vector real_sig; + BER_Decoder decoder(sig, length); + BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); + + BOTAN_ASSERT_NOMSG(m_parts != 0 && m_part_size != 0); + + size_t count = 0; + + while (ber_sig.more_items()) { + BigInt sig_part; + ber_sig.decode(sig_part); + real_sig += BigInt::encode_1363(sig_part, m_part_size); + ++count; + } + + if (count != m_parts) throw Decoding_Error("PK_Verifier: signature size invalid"); + + const std::vector reencoded = + der_encode_signature(real_sig, m_parts, m_part_size); + + if (reencoded.size() != length || + same_mem(reencoded.data(), sig, reencoded.size()) == false) { + throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding"); + } + + return m_op->is_valid_signature(real_sig.data(), real_sig.size()); + } else + throw Internal_Error("PK_Verifier: Invalid signature format enum"); + } catch (Invalid_Argument&) { + return false; + } +} + +} // namespace Botan /* -* Public Key Work Factor Functions -* (C) 1999-2007,2012 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Public Key Work Factor Functions + * (C) 1999-2007,2012 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #include namespace Botan { -size_t ecp_work_factor(size_t bits) - { - return bits / 2; - } +size_t ecp_work_factor(size_t bits) { return bits / 2; } namespace { -size_t nfs_workfactor(size_t bits, double k) - { - // approximates natural logarithm of integer of given bitsize - const double log2_e = std::log2(std::exp(1)); - const double log_p = bits / log2_e; +size_t nfs_workfactor(size_t bits, double k) { + // approximates natural logarithm of integer of given bitsize + const double log2_e = std::log2(std::exp(1)); + const double log_p = bits / log2_e; - const double log_log_p = std::log(log_p); + const double log_log_p = std::log(log_p); - // RFC 3766: k * e^((1.92 + o(1)) * cubrt(ln(n) * (ln(ln(n)))^2)) - const double est = 1.92 * std::pow(log_p * log_log_p * log_log_p, 1.0/3.0); - - // return log2 of the workfactor - return static_cast(std::log2(k) + log2_e * est); - } + // RFC 3766: k * e^((1.92 + o(1)) * cubrt(ln(n) * (ln(ln(n)))^2)) + const double est = 1.92 * std::pow(log_p * log_log_p * log_log_p, 1.0 / 3.0); + // return log2 of the workfactor + return static_cast(std::log2(k) + log2_e * est); } -size_t if_work_factor(size_t bits) - { - // RFC 3766 estimates k at .02 and o(1) to be effectively zero for sizes of interest +} // namespace - return nfs_workfactor(bits, .02); - } - -size_t dl_work_factor(size_t bits) - { - // Lacking better estimates... - return if_work_factor(bits); - } - -size_t dl_exponent_size(size_t bits) - { - /* - This uses a slightly tweaked version of the standard work factor - function above. It assumes k is 1 (thus overestimating the strength - of the prime group by 5-6 bits), and always returns at least 128 bits - (this only matters for very small primes). - */ - const size_t MIN_WORKFACTOR = 64; - - return 2 * std::max(MIN_WORKFACTOR, nfs_workfactor(bits, 1)); - } +size_t if_work_factor(size_t bits) { + // RFC 3766 estimates k at .02 and o(1) to be effectively zero for sizes of interest + return nfs_workfactor(bits, .02); } + +size_t dl_work_factor(size_t bits) { + // Lacking better estimates... + return if_work_factor(bits); +} + +size_t dl_exponent_size(size_t bits) { + /* + This uses a slightly tweaked version of the standard work factor + function above. It assumes k is 1 (thus overestimating the strength + of the prime group by 5-6 bits), and always returns at least 128 bits + (this only matters for very small primes). + */ + const size_t MIN_WORKFACTOR = 64; + + return 2 * std::max(MIN_WORKFACTOR, nfs_workfactor(bits, 1)); +} + +} // namespace Botan /* -* X.509 Public Key -* (C) 1999-2010 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * X.509 Public Key + * (C) 1999-2010 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace X509 { -std::vector BER_encode(const Public_Key& key) - { - // keeping it around for compat - return key.subject_public_key(); - } +std::vector BER_encode(const Public_Key& key) { + // keeping it around for compat + return key.subject_public_key(); +} /* -* PEM encode a X.509 public key -*/ -std::string PEM_encode(const Public_Key& key) - { - return PEM_Code::encode(key.subject_public_key(), - "PUBLIC KEY"); - } + * PEM encode a X.509 public key + */ +std::string PEM_encode(const Public_Key& key) { + return PEM_Code::encode(key.subject_public_key(), "PUBLIC KEY"); +} /* -* Extract a public key and return it -*/ -Public_Key* load_key(DataSource& source) - { - try { - AlgorithmIdentifier alg_id; - std::vector key_bits; + * Extract a public key and return it + */ +Public_Key* load_key(DataSource& source) { + try { + AlgorithmIdentifier alg_id; + std::vector key_bits; - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - { - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .end_cons(); - } - else - { - DataSource_Memory ber( - PEM_Code::decode_check_label(source, "PUBLIC KEY") - ); + if (ASN1::maybe_BER(source) && !PEM_Code::matches(source)) { + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .end_cons(); + } else { + DataSource_Memory ber(PEM_Code::decode_check_label(source, "PUBLIC KEY")); - BER_Decoder(ber) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .end_cons(); - } + BER_Decoder(ber) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .end_cons(); + } - if(key_bits.empty()) - throw Decoding_Error("X.509 public key decoding"); + if (key_bits.empty()) throw Decoding_Error("X.509 public key decoding"); - return load_public_key(alg_id, key_bits).release(); - } - catch(Decoding_Error& e) - { - throw Decoding_Error("X.509 public key decoding", e); - } - } + return load_public_key(alg_id, key_bits).release(); + } catch (Decoding_Error& e) { + throw Decoding_Error("X.509 public key decoding", e); + } +} #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) /* -* Extract a public key and return it -*/ -Public_Key* load_key(const std::string& fsname) - { - DataSource_Stream source(fsname, true); - return X509::load_key(source); - } + * Extract a public key and return it + */ +Public_Key* load_key(const std::string& fsname) { + DataSource_Stream source(fsname, true); + return X509::load_key(source); +} #endif /* -* Extract a public key and return it -*/ -Public_Key* load_key(const std::vector& mem) - { - DataSource_Memory source(mem); - return X509::load_key(source); - } - -/* -* Make a copy of this public key -*/ -Public_Key* copy_key(const Public_Key& key) - { - DataSource_Memory source(PEM_encode(key)); - return X509::load_key(source); - } - + * Extract a public key and return it + */ +Public_Key* load_key(const std::vector& mem) { + DataSource_Memory source(mem); + return X509::load_key(source); } -} /* -* (C) 2016 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Make a copy of this public key + */ +Public_Key* copy_key(const Public_Key& key) { + DataSource_Memory source(PEM_encode(key)); + return X509::load_key(source); +} +} // namespace X509 + +} // namespace Botan +/* + * (C) 2016 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_AUTO_SEEDING_RNG) #endif namespace Botan { -void RandomNumberGenerator::randomize_with_ts_input(uint8_t output[], size_t output_len) - { - if(this->accepts_input()) - { - /* - Form additional input which is provided to the PRNG implementation - to paramaterize the KDF output. - */ - uint8_t additional_input[16] = { 0 }; - store_le(OS::get_system_timestamp_ns(), additional_input); - store_le(OS::get_high_resolution_clock(), additional_input + 8); +void RandomNumberGenerator::randomize_with_ts_input(uint8_t output[], size_t output_len) { + if (this->accepts_input()) { + /* + Form additional input which is provided to the PRNG implementation + to paramaterize the KDF output. + */ + uint8_t additional_input[16] = {0}; + store_le(OS::get_system_timestamp_ns(), additional_input); + store_le(OS::get_high_resolution_clock(), additional_input + 8); - this->randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); - } - else - { - this->randomize(output, output_len); - } - } + this->randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); + } else { + this->randomize(output, output_len); + } +} void RandomNumberGenerator::randomize_with_input(uint8_t output[], size_t output_len, - const uint8_t input[], size_t input_len) - { - this->add_entropy(input, input_len); - this->randomize(output, output_len); - } + const uint8_t input[], size_t input_len) { + this->add_entropy(input, input_len); + this->randomize(output, output_len); +} -size_t RandomNumberGenerator::reseed(Entropy_Sources& srcs, - size_t poll_bits, - std::chrono::milliseconds poll_timeout) - { - if(this->accepts_input()) - { - return srcs.poll(*this, poll_bits, poll_timeout); - } - else - { - return 0; - } - } +size_t RandomNumberGenerator::reseed(Entropy_Sources& srcs, size_t poll_bits, + std::chrono::milliseconds poll_timeout) { + if (this->accepts_input()) { + return srcs.poll(*this, poll_bits, poll_timeout); + } else { + return 0; + } +} -void RandomNumberGenerator::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) - { - if(this->accepts_input()) - { - secure_vector buf(poll_bits / 8); - rng.randomize(buf.data(), buf.size()); - this->add_entropy(buf.data(), buf.size()); - } - } +void RandomNumberGenerator::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) { + if (this->accepts_input()) { + secure_vector buf(poll_bits / 8); + rng.randomize(buf.data(), buf.size()); + this->add_entropy(buf.data(), buf.size()); + } +} -RandomNumberGenerator* RandomNumberGenerator::make_rng() - { +RandomNumberGenerator* RandomNumberGenerator::make_rng() { #if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - return new AutoSeeded_RNG; + return new AutoSeeded_RNG; #else - throw Not_Implemented("make_rng failed, no AutoSeeded_RNG in this build"); + throw Not_Implemented("make_rng failed, no AutoSeeded_RNG in this build"); #endif - } +} #if defined(BOTAN_TARGET_OS_HAS_THREADS) #if defined(BOTAN_HAS_AUTO_SEEDING_RNG) Serialized_RNG::Serialized_RNG() : m_rng(new AutoSeeded_RNG) {} #else -Serialized_RNG::Serialized_RNG() - { - throw Not_Implemented("Serialized_RNG default constructor failed: AutoSeeded_RNG disabled in build"); - } -#endif - -#endif - +Serialized_RNG::Serialized_RNG() { + throw Not_Implemented( + "Serialized_RNG default constructor failed: AutoSeeded_RNG disabled in build"); } -/* -* SHA-160 -* (C) 1999-2008,2011 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +#endif +#endif + +} // namespace Botan +/* + * SHA-160 + * (C) 1999-2008,2011 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -std::unique_ptr SHA_160::copy_state() const - { - return std::unique_ptr(new SHA_160(*this)); - } +std::unique_ptr SHA_160::copy_state() const { + return std::unique_ptr(new SHA_160(*this)); +} namespace SHA1_F { namespace { /* -* SHA-160 F1 Function -*/ -inline void F1(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) - { - E += (D ^ (B & (C ^ D))) + msg + 0x5A827999 + rotl<5>(A); - B = rotl<30>(B); - } - -/* -* SHA-160 F2 Function -*/ -inline void F2(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) - { - E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotl<5>(A); - B = rotl<30>(B); - } - -/* -* SHA-160 F3 Function -*/ -inline void F3(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) - { - E += ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC + rotl<5>(A); - B = rotl<30>(B); - } - -/* -* SHA-160 F4 Function -*/ -inline void F4(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) - { - E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotl<5>(A); - B = rotl<30>(B); - } - -} - + * SHA-160 F1 Function + */ +inline void F1(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) { + E += (D ^ (B & (C ^ D))) + msg + 0x5A827999 + rotl<5>(A); + B = rotl<30>(B); } /* -* SHA-160 Compression Function -*/ -void SHA_160::compress_n(const uint8_t input[], size_t blocks) - { - using namespace SHA1_F; + * SHA-160 F2 Function + */ +inline void F2(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) { + E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotl<5>(A); + B = rotl<30>(B); +} + +/* + * SHA-160 F3 Function + */ +inline void F3(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) { + E += ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC + rotl<5>(A); + B = rotl<30>(B); +} + +/* + * SHA-160 F4 Function + */ +inline void F4(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) { + E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotl<5>(A); + B = rotl<30>(B); +} + +} // namespace + +} // namespace SHA1_F + +/* + * SHA-160 Compression Function + */ +void SHA_160::compress_n(const uint8_t input[], size_t blocks) { + using namespace SHA1_F; #if defined(BOTAN_HAS_SHA1_X86_SHA_NI) - if(CPUID::has_intel_sha()) - { - return sha1_compress_x86(m_digest, input, blocks); - } + if (CPUID::has_intel_sha()) { + return sha1_compress_x86(m_digest, input, blocks); + } #endif #if defined(BOTAN_HAS_SHA1_ARMV8) - if(CPUID::has_arm_sha1()) - { - return sha1_armv8_compress_n(m_digest, input, blocks); - } + if (CPUID::has_arm_sha1()) { + return sha1_armv8_compress_n(m_digest, input, blocks); + } #endif #if defined(BOTAN_HAS_SHA1_SSE2) - if(CPUID::has_sse2()) - { - return sse2_compress_n(m_digest, input, blocks); - } + if (CPUID::has_sse2()) { + return sse2_compress_n(m_digest, input, blocks); + } #endif - uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], - D = m_digest[3], E = m_digest[4]; + uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], D = m_digest[3], E = m_digest[4]; - m_W.resize(80); + m_W.resize(80); - for(size_t i = 0; i != blocks; ++i) - { - load_be(m_W.data(), input, 16); + for (size_t i = 0; i != blocks; ++i) { + load_be(m_W.data(), input, 16); - for(size_t j = 16; j != 80; j += 8) - { - m_W[j ] = rotl<1>(m_W[j-3] ^ m_W[j-8] ^ m_W[j-14] ^ m_W[j-16]); - m_W[j+1] = rotl<1>(m_W[j-2] ^ m_W[j-7] ^ m_W[j-13] ^ m_W[j-15]); - m_W[j+2] = rotl<1>(m_W[j-1] ^ m_W[j-6] ^ m_W[j-12] ^ m_W[j-14]); - m_W[j+3] = rotl<1>(m_W[j ] ^ m_W[j-5] ^ m_W[j-11] ^ m_W[j-13]); - m_W[j+4] = rotl<1>(m_W[j+1] ^ m_W[j-4] ^ m_W[j-10] ^ m_W[j-12]); - m_W[j+5] = rotl<1>(m_W[j+2] ^ m_W[j-3] ^ m_W[j- 9] ^ m_W[j-11]); - m_W[j+6] = rotl<1>(m_W[j+3] ^ m_W[j-2] ^ m_W[j- 8] ^ m_W[j-10]); - m_W[j+7] = rotl<1>(m_W[j+4] ^ m_W[j-1] ^ m_W[j- 7] ^ m_W[j- 9]); - } + for (size_t j = 16; j != 80; j += 8) { + m_W[j] = rotl<1>(m_W[j - 3] ^ m_W[j - 8] ^ m_W[j - 14] ^ m_W[j - 16]); + m_W[j + 1] = rotl<1>(m_W[j - 2] ^ m_W[j - 7] ^ m_W[j - 13] ^ m_W[j - 15]); + m_W[j + 2] = rotl<1>(m_W[j - 1] ^ m_W[j - 6] ^ m_W[j - 12] ^ m_W[j - 14]); + m_W[j + 3] = rotl<1>(m_W[j] ^ m_W[j - 5] ^ m_W[j - 11] ^ m_W[j - 13]); + m_W[j + 4] = rotl<1>(m_W[j + 1] ^ m_W[j - 4] ^ m_W[j - 10] ^ m_W[j - 12]); + m_W[j + 5] = rotl<1>(m_W[j + 2] ^ m_W[j - 3] ^ m_W[j - 9] ^ m_W[j - 11]); + m_W[j + 6] = rotl<1>(m_W[j + 3] ^ m_W[j - 2] ^ m_W[j - 8] ^ m_W[j - 10]); + m_W[j + 7] = rotl<1>(m_W[j + 4] ^ m_W[j - 1] ^ m_W[j - 7] ^ m_W[j - 9]); + } - F1(A, B, C, D, E, m_W[ 0]); F1(E, A, B, C, D, m_W[ 1]); - F1(D, E, A, B, C, m_W[ 2]); F1(C, D, E, A, B, m_W[ 3]); - F1(B, C, D, E, A, m_W[ 4]); F1(A, B, C, D, E, m_W[ 5]); - F1(E, A, B, C, D, m_W[ 6]); F1(D, E, A, B, C, m_W[ 7]); - F1(C, D, E, A, B, m_W[ 8]); F1(B, C, D, E, A, m_W[ 9]); - F1(A, B, C, D, E, m_W[10]); F1(E, A, B, C, D, m_W[11]); - F1(D, E, A, B, C, m_W[12]); F1(C, D, E, A, B, m_W[13]); - F1(B, C, D, E, A, m_W[14]); F1(A, B, C, D, E, m_W[15]); - F1(E, A, B, C, D, m_W[16]); F1(D, E, A, B, C, m_W[17]); - F1(C, D, E, A, B, m_W[18]); F1(B, C, D, E, A, m_W[19]); + F1(A, B, C, D, E, m_W[0]); + F1(E, A, B, C, D, m_W[1]); + F1(D, E, A, B, C, m_W[2]); + F1(C, D, E, A, B, m_W[3]); + F1(B, C, D, E, A, m_W[4]); + F1(A, B, C, D, E, m_W[5]); + F1(E, A, B, C, D, m_W[6]); + F1(D, E, A, B, C, m_W[7]); + F1(C, D, E, A, B, m_W[8]); + F1(B, C, D, E, A, m_W[9]); + F1(A, B, C, D, E, m_W[10]); + F1(E, A, B, C, D, m_W[11]); + F1(D, E, A, B, C, m_W[12]); + F1(C, D, E, A, B, m_W[13]); + F1(B, C, D, E, A, m_W[14]); + F1(A, B, C, D, E, m_W[15]); + F1(E, A, B, C, D, m_W[16]); + F1(D, E, A, B, C, m_W[17]); + F1(C, D, E, A, B, m_W[18]); + F1(B, C, D, E, A, m_W[19]); - F2(A, B, C, D, E, m_W[20]); F2(E, A, B, C, D, m_W[21]); - F2(D, E, A, B, C, m_W[22]); F2(C, D, E, A, B, m_W[23]); - F2(B, C, D, E, A, m_W[24]); F2(A, B, C, D, E, m_W[25]); - F2(E, A, B, C, D, m_W[26]); F2(D, E, A, B, C, m_W[27]); - F2(C, D, E, A, B, m_W[28]); F2(B, C, D, E, A, m_W[29]); - F2(A, B, C, D, E, m_W[30]); F2(E, A, B, C, D, m_W[31]); - F2(D, E, A, B, C, m_W[32]); F2(C, D, E, A, B, m_W[33]); - F2(B, C, D, E, A, m_W[34]); F2(A, B, C, D, E, m_W[35]); - F2(E, A, B, C, D, m_W[36]); F2(D, E, A, B, C, m_W[37]); - F2(C, D, E, A, B, m_W[38]); F2(B, C, D, E, A, m_W[39]); + F2(A, B, C, D, E, m_W[20]); + F2(E, A, B, C, D, m_W[21]); + F2(D, E, A, B, C, m_W[22]); + F2(C, D, E, A, B, m_W[23]); + F2(B, C, D, E, A, m_W[24]); + F2(A, B, C, D, E, m_W[25]); + F2(E, A, B, C, D, m_W[26]); + F2(D, E, A, B, C, m_W[27]); + F2(C, D, E, A, B, m_W[28]); + F2(B, C, D, E, A, m_W[29]); + F2(A, B, C, D, E, m_W[30]); + F2(E, A, B, C, D, m_W[31]); + F2(D, E, A, B, C, m_W[32]); + F2(C, D, E, A, B, m_W[33]); + F2(B, C, D, E, A, m_W[34]); + F2(A, B, C, D, E, m_W[35]); + F2(E, A, B, C, D, m_W[36]); + F2(D, E, A, B, C, m_W[37]); + F2(C, D, E, A, B, m_W[38]); + F2(B, C, D, E, A, m_W[39]); - F3(A, B, C, D, E, m_W[40]); F3(E, A, B, C, D, m_W[41]); - F3(D, E, A, B, C, m_W[42]); F3(C, D, E, A, B, m_W[43]); - F3(B, C, D, E, A, m_W[44]); F3(A, B, C, D, E, m_W[45]); - F3(E, A, B, C, D, m_W[46]); F3(D, E, A, B, C, m_W[47]); - F3(C, D, E, A, B, m_W[48]); F3(B, C, D, E, A, m_W[49]); - F3(A, B, C, D, E, m_W[50]); F3(E, A, B, C, D, m_W[51]); - F3(D, E, A, B, C, m_W[52]); F3(C, D, E, A, B, m_W[53]); - F3(B, C, D, E, A, m_W[54]); F3(A, B, C, D, E, m_W[55]); - F3(E, A, B, C, D, m_W[56]); F3(D, E, A, B, C, m_W[57]); - F3(C, D, E, A, B, m_W[58]); F3(B, C, D, E, A, m_W[59]); + F3(A, B, C, D, E, m_W[40]); + F3(E, A, B, C, D, m_W[41]); + F3(D, E, A, B, C, m_W[42]); + F3(C, D, E, A, B, m_W[43]); + F3(B, C, D, E, A, m_W[44]); + F3(A, B, C, D, E, m_W[45]); + F3(E, A, B, C, D, m_W[46]); + F3(D, E, A, B, C, m_W[47]); + F3(C, D, E, A, B, m_W[48]); + F3(B, C, D, E, A, m_W[49]); + F3(A, B, C, D, E, m_W[50]); + F3(E, A, B, C, D, m_W[51]); + F3(D, E, A, B, C, m_W[52]); + F3(C, D, E, A, B, m_W[53]); + F3(B, C, D, E, A, m_W[54]); + F3(A, B, C, D, E, m_W[55]); + F3(E, A, B, C, D, m_W[56]); + F3(D, E, A, B, C, m_W[57]); + F3(C, D, E, A, B, m_W[58]); + F3(B, C, D, E, A, m_W[59]); - F4(A, B, C, D, E, m_W[60]); F4(E, A, B, C, D, m_W[61]); - F4(D, E, A, B, C, m_W[62]); F4(C, D, E, A, B, m_W[63]); - F4(B, C, D, E, A, m_W[64]); F4(A, B, C, D, E, m_W[65]); - F4(E, A, B, C, D, m_W[66]); F4(D, E, A, B, C, m_W[67]); - F4(C, D, E, A, B, m_W[68]); F4(B, C, D, E, A, m_W[69]); - F4(A, B, C, D, E, m_W[70]); F4(E, A, B, C, D, m_W[71]); - F4(D, E, A, B, C, m_W[72]); F4(C, D, E, A, B, m_W[73]); - F4(B, C, D, E, A, m_W[74]); F4(A, B, C, D, E, m_W[75]); - F4(E, A, B, C, D, m_W[76]); F4(D, E, A, B, C, m_W[77]); - F4(C, D, E, A, B, m_W[78]); F4(B, C, D, E, A, m_W[79]); + F4(A, B, C, D, E, m_W[60]); + F4(E, A, B, C, D, m_W[61]); + F4(D, E, A, B, C, m_W[62]); + F4(C, D, E, A, B, m_W[63]); + F4(B, C, D, E, A, m_W[64]); + F4(A, B, C, D, E, m_W[65]); + F4(E, A, B, C, D, m_W[66]); + F4(D, E, A, B, C, m_W[67]); + F4(C, D, E, A, B, m_W[68]); + F4(B, C, D, E, A, m_W[69]); + F4(A, B, C, D, E, m_W[70]); + F4(E, A, B, C, D, m_W[71]); + F4(D, E, A, B, C, m_W[72]); + F4(C, D, E, A, B, m_W[73]); + F4(B, C, D, E, A, m_W[74]); + F4(A, B, C, D, E, m_W[75]); + F4(E, A, B, C, D, m_W[76]); + F4(D, E, A, B, C, m_W[77]); + F4(C, D, E, A, B, m_W[78]); + F4(B, C, D, E, A, m_W[79]); - A = (m_digest[0] += A); - B = (m_digest[1] += B); - C = (m_digest[2] += C); - D = (m_digest[3] += D); - E = (m_digest[4] += E); - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void SHA_160::copy_out(uint8_t output[]) - { - copy_out_vec_be(output, output_length(), m_digest); - } - -/* -* Clear memory of sensitive data -*/ -void SHA_160::clear() - { - MDx_HashFunction::clear(); - zeroise(m_W); - m_digest[0] = 0x67452301; - m_digest[1] = 0xEFCDAB89; - m_digest[2] = 0x98BADCFE; - m_digest[3] = 0x10325476; - m_digest[4] = 0xC3D2E1F0; - } + A = (m_digest[0] += A); + B = (m_digest[1] += B); + C = (m_digest[2] += C); + D = (m_digest[3] += D); + E = (m_digest[4] += E); + input += hash_block_size(); + } } -/* -* (C) 2016 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +/* + * Copy out the digest + */ +void SHA_160::copy_out(uint8_t output[]) { copy_out_vec_be(output, output_length(), m_digest); } + +/* + * Clear memory of sensitive data + */ +void SHA_160::clear() { + MDx_HashFunction::clear(); + zeroise(m_W); + m_digest[0] = 0x67452301; + m_digest[1] = 0xEFCDAB89; + m_digest[2] = 0x98BADCFE; + m_digest[3] = 0x10325476; + m_digest[4] = 0xC3D2E1F0; +} + +} // namespace Botan +/* + * (C) 2016 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_HAS_RDRAND_RNG) #endif namespace Botan { -void Stateful_RNG::clear() - { - m_reseed_counter = 0; - m_last_pid = 0; - } +void Stateful_RNG::clear() { + m_reseed_counter = 0; + m_last_pid = 0; +} -void Stateful_RNG::force_reseed() - { - m_reseed_counter = 0; - } +void Stateful_RNG::force_reseed() { m_reseed_counter = 0; } -bool Stateful_RNG::is_seeded() const - { - return m_reseed_counter > 0; - } +bool Stateful_RNG::is_seeded() const { return m_reseed_counter > 0; } -void Stateful_RNG::initialize_with(const uint8_t input[], size_t len) - { - add_entropy(input, len); +void Stateful_RNG::initialize_with(const uint8_t input[], size_t len) { + add_entropy(input, len); - if(8*len >= security_level()) - { - reset_reseed_counter(); - } - } + if (8 * len >= security_level()) { + reset_reseed_counter(); + } +} -void Stateful_RNG::randomize_with_ts_input(uint8_t output[], size_t output_len) - { - uint8_t additional_input[24] = { 0 }; +void Stateful_RNG::randomize_with_ts_input(uint8_t output[], size_t output_len) { + uint8_t additional_input[24] = {0}; #if defined(BOTAN_HAS_RDRAND_RNG) - if(RDRAND_RNG::available()) - { - RDRAND_RNG rdrand; - rdrand.randomize(additional_input, sizeof(additional_input)); - } - else + if (RDRAND_RNG::available()) { + RDRAND_RNG rdrand; + rdrand.randomize(additional_input, sizeof(additional_input)); + } else #endif - { - store_le(OS::get_system_timestamp_ns(), additional_input); - store_le(OS::get_high_resolution_clock(), additional_input + 8); - store_le(m_last_pid, additional_input + 16); - store_le(static_cast(m_reseed_counter), additional_input + 20); - } - - randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); - } - -size_t Stateful_RNG::reseed(Entropy_Sources& srcs, - size_t poll_bits, - std::chrono::milliseconds poll_timeout) - { - size_t bits_collected = RandomNumberGenerator::reseed(srcs, poll_bits, poll_timeout); - - if(bits_collected >= security_level()) - { - reset_reseed_counter(); - } - - return bits_collected; - } - -void Stateful_RNG::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) - { - RandomNumberGenerator::reseed_from_rng(rng, poll_bits); - - if(poll_bits >= security_level()) - { - reset_reseed_counter(); - } - } - -void Stateful_RNG::reseed_check() - { - const uint32_t cur_pid = OS::get_process_id(); - - const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid); - - if(is_seeded() == false || - fork_detected || - (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval)) - { - m_reseed_counter = 0; - m_last_pid = cur_pid; - - if(m_underlying_rng) - { - reseed_from_rng(*m_underlying_rng, security_level()); - } - - if(m_entropy_sources) - { - reseed(*m_entropy_sources, security_level()); - } - - if(!is_seeded()) - { - if(fork_detected) - throw Invalid_State("Detected use of fork but cannot reseed DRBG"); - else - throw PRNG_Unseeded(name()); - } - } - else - { - BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded"); - m_reseed_counter += 1; - } - } + { + store_le(OS::get_system_timestamp_ns(), additional_input); + store_le(OS::get_high_resolution_clock(), additional_input + 8); + store_le(m_last_pid, additional_input + 16); + store_le(static_cast(m_reseed_counter), additional_input + 20); + } + randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); } -/* -* Runtime assertion checking -* (C) 2010,2012,2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +size_t Stateful_RNG::reseed(Entropy_Sources& srcs, size_t poll_bits, + std::chrono::milliseconds poll_timeout) { + size_t bits_collected = RandomNumberGenerator::reseed(srcs, poll_bits, poll_timeout); + + if (bits_collected >= security_level()) { + reset_reseed_counter(); + } + + return bits_collected; +} + +void Stateful_RNG::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) { + RandomNumberGenerator::reseed_from_rng(rng, poll_bits); + + if (poll_bits >= security_level()) { + reset_reseed_counter(); + } +} + +void Stateful_RNG::reseed_check() { + const uint32_t cur_pid = OS::get_process_id(); + + const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid); + + if (is_seeded() == false || fork_detected || + (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval)) { + m_reseed_counter = 0; + m_last_pid = cur_pid; + + if (m_underlying_rng) { + reseed_from_rng(*m_underlying_rng, security_level()); + } + + if (m_entropy_sources) { + reseed(*m_entropy_sources, security_level()); + } + + if (!is_seeded()) { + if (fork_detected) + throw Invalid_State("Detected use of fork but cannot reseed DRBG"); + else + throw PRNG_Unseeded(name()); + } + } else { + BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded"); + m_reseed_counter += 1; + } +} + +} // namespace Botan +/* + * Runtime assertion checking + * (C) 2010,2012,2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -void throw_invalid_argument(const char* message, - const char* func, - const char* file) - { - std::ostringstream format; - format << message << " in " << func << ":" << file; - throw Invalid_Argument(format.str()); - } - -void throw_invalid_state(const char* expr, - const char* func, - const char* file) - { - std::ostringstream format; - format << "Invalid state: " << expr << " was false in " << func << ":" << file; - throw Invalid_State(format.str()); - } - -void assertion_failure(const char* expr_str, - const char* assertion_made, - const char* func, - const char* file, - int line) - { - std::ostringstream format; - - format << "False assertion "; - - if(assertion_made && assertion_made[0] != 0) - format << "'" << assertion_made << "' (expression " << expr_str << ") "; - else - format << expr_str << " "; - - if(func) - format << "in " << func << " "; - - format << "@" << file << ":" << line; - - throw Internal_Error(format.str()); - } - +void throw_invalid_argument(const char* message, const char* func, const char* file) { + std::ostringstream format; + format << message << " in " << func << ":" << file; + throw Invalid_Argument(format.str()); } + +void throw_invalid_state(const char* expr, const char* func, const char* file) { + std::ostringstream format; + format << "Invalid state: " << expr << " was false in " << func << ":" << file; + throw Invalid_State(format.str()); +} + +void assertion_failure(const char* expr_str, const char* assertion_made, const char* func, + const char* file, int line) { + std::ostringstream format; + + format << "False assertion "; + + if (assertion_made && assertion_made[0] != 0) + format << "'" << assertion_made << "' (expression " << expr_str << ") "; + else + format << expr_str << " "; + + if (func) format << "in " << func << " "; + + format << "@" << file << ":" << line; + + throw Internal_Error(format.str()); +} + +} // namespace Botan /* -* Calendar Functions -* (C) 1999-2010,2017 Jack Lloyd -* (C) 2015 Simon Warta (Kullo GmbH) -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Calendar Functions + * (C) 1999-2010,2017 Jack Lloyd + * (C) 2015 Simon Warta (Kullo GmbH) + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +#include #include -#include namespace Botan { namespace { -std::tm do_gmtime(std::time_t time_val) - { - std::tm tm; +std::tm do_gmtime(std::time_t time_val) { + std::tm tm; #if defined(BOTAN_TARGET_OS_HAS_WIN32) - ::gmtime_s(&tm, &time_val); // Windows + ::gmtime_s(&tm, &time_val); // Windows #elif defined(BOTAN_TARGET_OS_HAS_POSIX1) - ::gmtime_r(&time_val, &tm); // Unix/SUSv2 + ::gmtime_r(&time_val, &tm); // Unix/SUSv2 #else - std::tm* tm_p = std::gmtime(&time_val); - if (tm_p == nullptr) - throw Encoding_Error("time_t_to_tm could not convert"); - tm = *tm_p; + std::tm* tm_p = std::gmtime(&time_val); + if (tm_p == nullptr) throw Encoding_Error("time_t_to_tm could not convert"); + tm = *tm_p; #endif - return tm; - } + return tm; +} /* Portable replacement for timegm, _mkgmtime, etc @@ -24125,850 +21672,710 @@ See https://howardhinnant.github.io/date_algorithms.html#days_from_civil for details and explaination. The code is slightly simplified by our assumption that the date is at least 1970, which is sufficient for our purposes. */ -size_t days_since_epoch(uint32_t year, uint32_t month, uint32_t day) - { - if(month <= 2) - year -= 1; - const uint32_t era = year / 400; - const uint32_t yoe = year - era * 400; // [0, 399] - const uint32_t doy = (153*(month + (month > 2 ? -3 : 9)) + 2)/5 + day-1; // [0, 365] - const uint32_t doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] - return era * 146097 + doe - 719468; - } - +size_t days_since_epoch(uint32_t year, uint32_t month, uint32_t day) { + if (month <= 2) year -= 1; + const uint32_t era = year / 400; + const uint32_t yoe = year - era * 400; // [0, 399] + const uint32_t doy = (153 * (month + (month > 2 ? -3 : 9)) + 2) / 5 + day - 1; // [0, 365] + const uint32_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096] + return era * 146097 + doe - 719468; } -std::chrono::system_clock::time_point calendar_point::to_std_timepoint() const - { - if(get_year() < 1970) - throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years before 1970"); +} // namespace - // 32 bit time_t ends at January 19, 2038 - // https://msdn.microsoft.com/en-us/library/2093ets1.aspx - // Throw after 2037 if 32 bit time_t is used +std::chrono::system_clock::time_point calendar_point::to_std_timepoint() const { + if (get_year() < 1970) + throw Invalid_Argument( + "calendar_point::to_std_timepoint() does not support years before 1970"); - BOTAN_IF_CONSTEXPR(sizeof(std::time_t) == 4) - { - if(get_year() > 2037) - { - throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years after 2037 on this system"); - } - } + // 32 bit time_t ends at January 19, 2038 + // https://msdn.microsoft.com/en-us/library/2093ets1.aspx + // Throw after 2037 if 32 bit time_t is used - // This upper bound is completely arbitrary - if(get_year() >= 2400) - { - throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years after 2400"); - } + BOTAN_IF_CONSTEXPR(sizeof(std::time_t) == 4) { + if (get_year() > 2037) { + throw Invalid_Argument( + "calendar_point::to_std_timepoint() does not support years after 2037 on this " + "system"); + } + } - const uint64_t seconds_64 = (days_since_epoch(get_year(), get_month(), get_day()) * 86400) + + // This upper bound is completely arbitrary + if (get_year() >= 2400) { + throw Invalid_Argument( + "calendar_point::to_std_timepoint() does not support years after 2400"); + } + + const uint64_t seconds_64 = (days_since_epoch(get_year(), get_month(), get_day()) * 86400) + (get_hour() * 60 * 60) + (get_minutes() * 60) + get_seconds(); - const time_t seconds_time_t = static_cast(seconds_64); + const time_t seconds_time_t = static_cast(seconds_64); - if(seconds_64 - seconds_time_t != 0) - { - throw Invalid_Argument("calendar_point::to_std_timepoint time_t overflow"); - } - - return std::chrono::system_clock::from_time_t(seconds_time_t); - } - -std::string calendar_point::to_string() const - { - // desired format: --
T:: - std::stringstream output; - output << std::setfill('0') - << std::setw(4) << get_year() << "-" - << std::setw(2) << get_month() << "-" - << std::setw(2) << get_day() << "T" - << std::setw(2) << get_hour() << ":" - << std::setw(2) << get_minutes() << ":" - << std::setw(2) << get_seconds(); - return output.str(); - } - - -calendar_point calendar_value( - const std::chrono::system_clock::time_point& time_point) - { - std::tm tm = do_gmtime(std::chrono::system_clock::to_time_t(time_point)); - - return calendar_point(tm.tm_year + 1900, - tm.tm_mon + 1, - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec); - } + if (seconds_64 - seconds_time_t != 0) { + throw Invalid_Argument("calendar_point::to_std_timepoint time_t overflow"); + } + return std::chrono::system_clock::from_time_t(seconds_time_t); } -/* -* Character Set Handling -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +std::string calendar_point::to_string() const { + // desired format: --
T:: + std::stringstream output; + output << std::setfill('0') << std::setw(4) << get_year() << "-" << std::setw(2) << get_month() + << "-" << std::setw(2) << get_day() << "T" << std::setw(2) << get_hour() << ":" + << std::setw(2) << get_minutes() << ":" << std::setw(2) << get_seconds(); + return output.str(); +} + +calendar_point calendar_value(const std::chrono::system_clock::time_point& time_point) { + std::tm tm = do_gmtime(std::chrono::system_clock::to_time_t(time_point)); + + return calendar_point(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, + tm.tm_sec); +} + +} // namespace Botan +/* + * Character Set Handling + * (C) 1999-2007 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace { -void append_utf8_for(std::string& s, uint32_t c) - { - if(c >= 0xD800 && c < 0xE000) - throw Decoding_Error("Invalid Unicode character"); - - if(c <= 0x7F) - { - const uint8_t b0 = static_cast(c); - s.push_back(static_cast(b0)); - } - else if(c <= 0x7FF) - { - const uint8_t b0 = 0xC0 | static_cast(c >> 6); - const uint8_t b1 = 0x80 | static_cast(c & 0x3F); - s.push_back(static_cast(b0)); - s.push_back(static_cast(b1)); - } - else if(c <= 0xFFFF) - { - const uint8_t b0 = 0xE0 | static_cast(c >> 12); - const uint8_t b1 = 0x80 | static_cast((c >> 6) & 0x3F); - const uint8_t b2 = 0x80 | static_cast(c & 0x3F); - s.push_back(static_cast(b0)); - s.push_back(static_cast(b1)); - s.push_back(static_cast(b2)); - } - else if(c <= 0x10FFFF) - { - const uint8_t b0 = 0xF0 | static_cast(c >> 18); - const uint8_t b1 = 0x80 | static_cast((c >> 12) & 0x3F); - const uint8_t b2 = 0x80 | static_cast((c >> 6) & 0x3F); - const uint8_t b3 = 0x80 | static_cast(c & 0x3F); - s.push_back(static_cast(b0)); - s.push_back(static_cast(b1)); - s.push_back(static_cast(b2)); - s.push_back(static_cast(b3)); - } - else - throw Decoding_Error("Invalid Unicode character"); - - } +void append_utf8_for(std::string& s, uint32_t c) { + if (c >= 0xD800 && c < 0xE000) throw Decoding_Error("Invalid Unicode character"); + if (c <= 0x7F) { + const uint8_t b0 = static_cast(c); + s.push_back(static_cast(b0)); + } else if (c <= 0x7FF) { + const uint8_t b0 = 0xC0 | static_cast(c >> 6); + const uint8_t b1 = 0x80 | static_cast(c & 0x3F); + s.push_back(static_cast(b0)); + s.push_back(static_cast(b1)); + } else if (c <= 0xFFFF) { + const uint8_t b0 = 0xE0 | static_cast(c >> 12); + const uint8_t b1 = 0x80 | static_cast((c >> 6) & 0x3F); + const uint8_t b2 = 0x80 | static_cast(c & 0x3F); + s.push_back(static_cast(b0)); + s.push_back(static_cast(b1)); + s.push_back(static_cast(b2)); + } else if (c <= 0x10FFFF) { + const uint8_t b0 = 0xF0 | static_cast(c >> 18); + const uint8_t b1 = 0x80 | static_cast((c >> 12) & 0x3F); + const uint8_t b2 = 0x80 | static_cast((c >> 6) & 0x3F); + const uint8_t b3 = 0x80 | static_cast(c & 0x3F); + s.push_back(static_cast(b0)); + s.push_back(static_cast(b1)); + s.push_back(static_cast(b2)); + s.push_back(static_cast(b3)); + } else + throw Decoding_Error("Invalid Unicode character"); } -std::string ucs2_to_utf8(const uint8_t ucs2[], size_t len) - { - if(len % 2 != 0) - throw Decoding_Error("Invalid length for UCS-2 string"); +} // namespace - const size_t chars = len / 2; +std::string ucs2_to_utf8(const uint8_t ucs2[], size_t len) { + if (len % 2 != 0) throw Decoding_Error("Invalid length for UCS-2 string"); - std::string s; - for(size_t i = 0; i != chars; ++i) - { - const uint16_t c = load_be(ucs2, i); - append_utf8_for(s, c); - } + const size_t chars = len / 2; - return s; - } + std::string s; + for (size_t i = 0; i != chars; ++i) { + const uint16_t c = load_be(ucs2, i); + append_utf8_for(s, c); + } -std::string ucs4_to_utf8(const uint8_t ucs4[], size_t len) - { - if(len % 4 != 0) - throw Decoding_Error("Invalid length for UCS-4 string"); + return s; +} - const size_t chars = len / 4; +std::string ucs4_to_utf8(const uint8_t ucs4[], size_t len) { + if (len % 4 != 0) throw Decoding_Error("Invalid length for UCS-4 string"); - std::string s; - for(size_t i = 0; i != chars; ++i) - { - const uint32_t c = load_be(ucs4, i); - append_utf8_for(s, c); - } + const size_t chars = len / 4; - return s; - } + std::string s; + for (size_t i = 0; i != chars; ++i) { + const uint32_t c = load_be(ucs4, i); + append_utf8_for(s, c); + } + + return s; +} /* -* Convert from UTF-8 to ISO 8859-1 -*/ -std::string utf8_to_latin1(const std::string& utf8) - { - std::string iso8859; + * Convert from UTF-8 to ISO 8859-1 + */ +std::string utf8_to_latin1(const std::string& utf8) { + std::string iso8859; - size_t position = 0; - while(position != utf8.size()) - { - const uint8_t c1 = static_cast(utf8[position++]); + size_t position = 0; + while (position != utf8.size()) { + const uint8_t c1 = static_cast(utf8[position++]); - if(c1 <= 0x7F) - { - iso8859 += static_cast(c1); - } - else if(c1 >= 0xC0 && c1 <= 0xC7) - { - if(position == utf8.size()) - throw Decoding_Error("UTF-8: sequence truncated"); + if (c1 <= 0x7F) { + iso8859 += static_cast(c1); + } else if (c1 >= 0xC0 && c1 <= 0xC7) { + if (position == utf8.size()) throw Decoding_Error("UTF-8: sequence truncated"); - const uint8_t c2 = static_cast(utf8[position++]); - const uint8_t iso_char = ((c1 & 0x07) << 6) | (c2 & 0x3F); + const uint8_t c2 = static_cast(utf8[position++]); + const uint8_t iso_char = ((c1 & 0x07) << 6) | (c2 & 0x3F); - if(iso_char <= 0x7F) - throw Decoding_Error("UTF-8: sequence longer than needed"); + if (iso_char <= 0x7F) throw Decoding_Error("UTF-8: sequence longer than needed"); - iso8859 += static_cast(iso_char); - } - else - throw Decoding_Error("UTF-8: Unicode chars not in Latin1 used"); - } + iso8859 += static_cast(iso_char); + } else + throw Decoding_Error("UTF-8: Unicode chars not in Latin1 used"); + } - return iso8859; - } + return iso8859; +} namespace Charset { namespace { /* -* Convert from UCS-2 to ISO 8859-1 -*/ -std::string ucs2_to_latin1(const std::string& ucs2) - { - if(ucs2.size() % 2 == 1) - throw Decoding_Error("UCS-2 string has an odd number of bytes"); + * Convert from UCS-2 to ISO 8859-1 + */ +std::string ucs2_to_latin1(const std::string& ucs2) { + if (ucs2.size() % 2 == 1) throw Decoding_Error("UCS-2 string has an odd number of bytes"); - std::string latin1; + std::string latin1; - for(size_t i = 0; i != ucs2.size(); i += 2) - { - const uint8_t c1 = ucs2[i]; - const uint8_t c2 = ucs2[i+1]; + for (size_t i = 0; i != ucs2.size(); i += 2) { + const uint8_t c1 = ucs2[i]; + const uint8_t c2 = ucs2[i + 1]; - if(c1 != 0) - throw Decoding_Error("UCS-2 has non-Latin1 characters"); + if (c1 != 0) throw Decoding_Error("UCS-2 has non-Latin1 characters"); - latin1 += static_cast(c2); - } - - return latin1; - } - -/* -* Convert from ISO 8859-1 to UTF-8 -*/ -std::string latin1_to_utf8(const std::string& iso8859) - { - std::string utf8; - for(size_t i = 0; i != iso8859.size(); ++i) - { - const uint8_t c = static_cast(iso8859[i]); - - if(c <= 0x7F) - utf8 += static_cast(c); - else - { - utf8 += static_cast((0xC0 | (c >> 6))); - utf8 += static_cast((0x80 | (c & 0x3F))); - } - } - return utf8; - } + latin1 += static_cast(c2); + } + return latin1; } /* -* Perform character set transcoding -*/ -std::string transcode(const std::string& str, - Character_Set to, Character_Set from) - { - if(to == LOCAL_CHARSET) - to = LATIN1_CHARSET; - if(from == LOCAL_CHARSET) - from = LATIN1_CHARSET; - - if(to == from) - return str; - - if(from == LATIN1_CHARSET && to == UTF8_CHARSET) - return latin1_to_utf8(str); - if(from == UTF8_CHARSET && to == LATIN1_CHARSET) - return utf8_to_latin1(str); - if(from == UCS2_CHARSET && to == LATIN1_CHARSET) - return ucs2_to_latin1(str); - - throw Invalid_Argument("Unknown transcoding operation from " + - std::to_string(from) + " to " + std::to_string(to)); - } - -/* -* Check if a character represents a digit -*/ -bool is_digit(char c) - { - if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || - c == '5' || c == '6' || c == '7' || c == '8' || c == '9') - return true; - return false; - } - -/* -* Check if a character represents whitespace -*/ -bool is_space(char c) - { - if(c == ' ' || c == '\t' || c == '\n' || c == '\r') - return true; - return false; - } - -/* -* Convert a character to a digit -*/ -uint8_t char2digit(char c) - { - switch(c) - { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - } - - throw Invalid_Argument("char2digit: Input is not a digit character"); - } - -/* -* Convert a digit to a character -*/ -char digit2char(uint8_t b) - { - switch(b) - { - case 0: return '0'; - case 1: return '1'; - case 2: return '2'; - case 3: return '3'; - case 4: return '4'; - case 5: return '5'; - case 6: return '6'; - case 7: return '7'; - case 8: return '8'; - case 9: return '9'; - } - - throw Invalid_Argument("digit2char: Input is not a digit"); - } - -/* -* Case-insensitive character comparison -*/ -bool caseless_cmp(char a, char b) - { - return (std::tolower(static_cast(a)) == - std::tolower(static_cast(b))); - } + * Convert from ISO 8859-1 to UTF-8 + */ +std::string latin1_to_utf8(const std::string& iso8859) { + std::string utf8; + for (size_t i = 0; i != iso8859.size(); ++i) { + const uint8_t c = static_cast(iso8859[i]); + if (c <= 0x7F) + utf8 += static_cast(c); + else { + utf8 += static_cast((0xC0 | (c >> 6))); + utf8 += static_cast((0x80 | (c & 0x3F))); + } + } + return utf8; } -} -/* -* (C) 2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace +/* + * Perform character set transcoding + */ +std::string transcode(const std::string& str, Character_Set to, Character_Set from) { + if (to == LOCAL_CHARSET) to = LATIN1_CHARSET; + if (from == LOCAL_CHARSET) from = LATIN1_CHARSET; + + if (to == from) return str; + + if (from == LATIN1_CHARSET && to == UTF8_CHARSET) return latin1_to_utf8(str); + if (from == UTF8_CHARSET && to == LATIN1_CHARSET) return utf8_to_latin1(str); + if (from == UCS2_CHARSET && to == LATIN1_CHARSET) return ucs2_to_latin1(str); + + throw Invalid_Argument("Unknown transcoding operation from " + std::to_string(from) + " to " + + std::to_string(to)); +} + +/* + * Check if a character represents a digit + */ +bool is_digit(char c) { + if (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || + c == '7' || c == '8' || c == '9') + return true; + return false; +} + +/* + * Check if a character represents whitespace + */ +bool is_space(char c) { + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') return true; + return false; +} + +/* + * Convert a character to a digit + */ +uint8_t char2digit(char c) { + switch (c) { + case '0': + return 0; + case '1': + return 1; + case '2': + return 2; + case '3': + return 3; + case '4': + return 4; + case '5': + return 5; + case '6': + return 6; + case '7': + return 7; + case '8': + return 8; + case '9': + return 9; + } + + throw Invalid_Argument("char2digit: Input is not a digit character"); +} + +/* + * Convert a digit to a character + */ +char digit2char(uint8_t b) { + switch (b) { + case 0: + return '0'; + case 1: + return '1'; + case 2: + return '2'; + case 3: + return '3'; + case 4: + return '4'; + case 5: + return '5'; + case 6: + return '6'; + case 7: + return '7'; + case 8: + return '8'; + case 9: + return '9'; + } + + throw Invalid_Argument("digit2char: Input is not a digit"); +} + +/* + * Case-insensitive character comparison + */ +bool caseless_cmp(char a, char b) { + return (std::tolower(static_cast(a)) == + std::tolower(static_cast(b))); +} + +} // namespace Charset + +} // namespace Botan +/* + * (C) 2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { namespace CT { -secure_vector copy_output(CT::Mask bad_input, - const uint8_t input[], - size_t input_length, - size_t offset) - { - if(input_length == 0) - return secure_vector(); +secure_vector copy_output(CT::Mask bad_input, const uint8_t input[], + size_t input_length, size_t offset) { + if (input_length == 0) return secure_vector(); - /* - * Ensure at runtime that offset <= input_length. This is an invalid input, - * but we can't throw without using the poisoned value. Instead, if it happens, - * set offset to be equal to the input length (so output_bytes becomes 0 and - * the returned vector is empty) - */ - const auto valid_offset = CT::Mask::is_lte(offset, input_length); - offset = valid_offset.select(offset, input_length); + /* + * Ensure at runtime that offset <= input_length. This is an invalid input, + * but we can't throw without using the poisoned value. Instead, if it happens, + * set offset to be equal to the input length (so output_bytes becomes 0 and + * the returned vector is empty) + */ + const auto valid_offset = CT::Mask::is_lte(offset, input_length); + offset = valid_offset.select(offset, input_length); - const size_t output_bytes = input_length - offset; + const size_t output_bytes = input_length - offset; - secure_vector output(input_length); + secure_vector output(input_length); - /* - Move the desired output bytes to the front using a slow (O^n) - but constant time loop that does not leak the value of the offset - */ - for(size_t i = 0; i != input_length; ++i) - { - /* - start index from i rather than 0 since we know j must be >= i + offset - to have any effect, and starting from i does not reveal information - */ - for(size_t j = i; j != input_length; ++j) - { - const uint8_t b = input[j]; - const auto is_eq = CT::Mask::is_equal(j, offset + i); - output[i] |= is_eq.if_set_return(b); - } - } + /* + Move the desired output bytes to the front using a slow (O^n) + but constant time loop that does not leak the value of the offset + */ + for (size_t i = 0; i != input_length; ++i) { + /* + start index from i rather than 0 since we know j must be >= i + offset + to have any effect, and starting from i does not reveal information + */ + for (size_t j = i; j != input_length; ++j) { + const uint8_t b = input[j]; + const auto is_eq = CT::Mask::is_equal(j, offset + i); + output[i] |= is_eq.if_set_return(b); + } + } - bad_input.if_set_zero_out(output.data(), output.size()); - - /* - This is potentially not const time, depending on how std::vector is - implemented. But since we are always reducing length, it should - just amount to setting the member var holding the length. - */ - CT::unpoison(output.data(), output.size()); - CT::unpoison(output_bytes); - output.resize(output_bytes); - return output; - } - -secure_vector strip_leading_zeros(const uint8_t in[], size_t length) - { - size_t leading_zeros = 0; - - auto only_zeros = Mask::set(); - - for(size_t i = 0; i != length; ++i) - { - only_zeros &= CT::Mask::is_zero(in[i]); - leading_zeros += only_zeros.if_set_return(1); - } - - return copy_output(CT::Mask::cleared(), in, length, leading_zeros); - } + bad_input.if_set_zero_out(output.data(), output.size()); + /* + This is potentially not const time, depending on how std::vector is + implemented. But since we are always reducing length, it should + just amount to setting the member var holding the length. + */ + CT::unpoison(output.data(), output.size()); + CT::unpoison(output_bytes); + output.resize(output_bytes); + return output; } +secure_vector strip_leading_zeros(const uint8_t in[], size_t length) { + size_t leading_zeros = 0; + + auto only_zeros = Mask::set(); + + for (size_t i = 0; i != length; ++i) { + only_zeros &= CT::Mask::is_zero(in[i]); + leading_zeros += only_zeros.if_set_return(1); + } + + return copy_output(CT::Mask::cleared(), in, length, leading_zeros); } + +} // namespace CT + +} // namespace Botan /* -* DataSource -* (C) 1999-2007 Jack Lloyd -* 2005 Matthew Gregan -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * DataSource + * (C) 1999-2007 Jack Lloyd + * 2005 Matthew Gregan + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) - #include +#include #endif namespace Botan { /* -* Read a single byte from the DataSource -*/ -size_t DataSource::read_byte(uint8_t& out) - { - return read(&out, 1); - } + * Read a single byte from the DataSource + */ +size_t DataSource::read_byte(uint8_t& out) { return read(&out, 1); } /* -* Peek a single byte from the DataSource -*/ -size_t DataSource::peek_byte(uint8_t& out) const - { - return peek(&out, 1, 0); - } + * Peek a single byte from the DataSource + */ +size_t DataSource::peek_byte(uint8_t& out) const { return peek(&out, 1, 0); } /* -* Discard the next N bytes of the data -*/ -size_t DataSource::discard_next(size_t n) - { - uint8_t buf[64] = { 0 }; - size_t discarded = 0; + * Discard the next N bytes of the data + */ +size_t DataSource::discard_next(size_t n) { + uint8_t buf[64] = {0}; + size_t discarded = 0; - while(n) - { - const size_t got = this->read(buf, std::min(n, sizeof(buf))); - discarded += got; - n -= got; + while (n) { + const size_t got = this->read(buf, std::min(n, sizeof(buf))); + discarded += got; + n -= got; - if(got == 0) - break; - } + if (got == 0) break; + } - return discarded; - } + return discarded; +} /* -* Read from a memory buffer -*/ -size_t DataSource_Memory::read(uint8_t out[], size_t length) - { - const size_t got = std::min(m_source.size() - m_offset, length); - copy_mem(out, m_source.data() + m_offset, got); - m_offset += got; - return got; - } + * Read from a memory buffer + */ +size_t DataSource_Memory::read(uint8_t out[], size_t length) { + const size_t got = std::min(m_source.size() - m_offset, length); + copy_mem(out, m_source.data() + m_offset, got); + m_offset += got; + return got; +} -bool DataSource_Memory::check_available(size_t n) - { - return (n <= (m_source.size() - m_offset)); - } +bool DataSource_Memory::check_available(size_t n) { return (n <= (m_source.size() - m_offset)); } /* -* Peek into a memory buffer -*/ -size_t DataSource_Memory::peek(uint8_t out[], size_t length, - size_t peek_offset) const - { - const size_t bytes_left = m_source.size() - m_offset; - if(peek_offset >= bytes_left) return 0; + * Peek into a memory buffer + */ +size_t DataSource_Memory::peek(uint8_t out[], size_t length, size_t peek_offset) const { + const size_t bytes_left = m_source.size() - m_offset; + if (peek_offset >= bytes_left) return 0; - const size_t got = std::min(bytes_left - peek_offset, length); - copy_mem(out, &m_source[m_offset + peek_offset], got); - return got; - } + const size_t got = std::min(bytes_left - peek_offset, length); + copy_mem(out, &m_source[m_offset + peek_offset], got); + return got; +} /* -* Check if the memory buffer is empty -*/ -bool DataSource_Memory::end_of_data() const - { - return (m_offset == m_source.size()); - } + * Check if the memory buffer is empty + */ +bool DataSource_Memory::end_of_data() const { return (m_offset == m_source.size()); } /* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const std::string& in) : - m_source(cast_char_ptr_to_uint8(in.data()), - cast_char_ptr_to_uint8(in.data()) + in.length()), - m_offset(0) - { - } + * DataSource_Memory Constructor + */ +DataSource_Memory::DataSource_Memory(const std::string& in) + : m_source(cast_char_ptr_to_uint8(in.data()), cast_char_ptr_to_uint8(in.data()) + in.length()), + m_offset(0) {} /* -* Read from a stream -*/ -size_t DataSource_Stream::read(uint8_t out[], size_t length) - { - m_source.read(cast_uint8_ptr_to_char(out), length); - if(m_source.bad()) - throw Stream_IO_Error("DataSource_Stream::read: Source failure"); + * Read from a stream + */ +size_t DataSource_Stream::read(uint8_t out[], size_t length) { + m_source.read(cast_uint8_ptr_to_char(out), length); + if (m_source.bad()) throw Stream_IO_Error("DataSource_Stream::read: Source failure"); - const size_t got = static_cast(m_source.gcount()); - m_total_read += got; - return got; - } + const size_t got = static_cast(m_source.gcount()); + m_total_read += got; + return got; +} -bool DataSource_Stream::check_available(size_t n) - { - const std::streampos orig_pos = m_source.tellg(); - m_source.seekg(0, std::ios::end); - const size_t avail = static_cast(m_source.tellg() - orig_pos); - m_source.seekg(orig_pos); - return (avail >= n); - } +bool DataSource_Stream::check_available(size_t n) { + const std::streampos orig_pos = m_source.tellg(); + m_source.seekg(0, std::ios::end); + const size_t avail = static_cast(m_source.tellg() - orig_pos); + m_source.seekg(orig_pos); + return (avail >= n); +} /* -* Peek into a stream -*/ -size_t DataSource_Stream::peek(uint8_t out[], size_t length, size_t offset) const - { - if(end_of_data()) - throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); + * Peek into a stream + */ +size_t DataSource_Stream::peek(uint8_t out[], size_t length, size_t offset) const { + if (end_of_data()) throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); - size_t got = 0; + size_t got = 0; - if(offset) - { - secure_vector buf(offset); - m_source.read(cast_uint8_ptr_to_char(buf.data()), buf.size()); - if(m_source.bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = static_cast(m_source.gcount()); - } + if (offset) { + secure_vector buf(offset); + m_source.read(cast_uint8_ptr_to_char(buf.data()), buf.size()); + if (m_source.bad()) throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = static_cast(m_source.gcount()); + } - if(got == offset) - { - m_source.read(cast_uint8_ptr_to_char(out), length); - if(m_source.bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = static_cast(m_source.gcount()); - } + if (got == offset) { + m_source.read(cast_uint8_ptr_to_char(out), length); + if (m_source.bad()) throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = static_cast(m_source.gcount()); + } - if(m_source.eof()) - m_source.clear(); - m_source.seekg(m_total_read, std::ios::beg); + if (m_source.eof()) m_source.clear(); + m_source.seekg(m_total_read, std::ios::beg); - return got; - } + return got; +} /* -* Check if the stream is empty or in error -*/ -bool DataSource_Stream::end_of_data() const - { - return (!m_source.good()); - } + * Check if the stream is empty or in error + */ +bool DataSource_Stream::end_of_data() const { return (!m_source.good()); } /* -* Return a human-readable ID for this stream -*/ -std::string DataSource_Stream::id() const - { - return m_identifier; - } + * Return a human-readable ID for this stream + */ +std::string DataSource_Stream::id() const { return m_identifier; } #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) /* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(const std::string& path, - bool use_binary) : - m_identifier(path), - m_source_memory(new std::ifstream(path, use_binary ? std::ios::binary : std::ios::in)), - m_source(*m_source_memory), - m_total_read(0) - { - if(!m_source.good()) - { - throw Stream_IO_Error("DataSource: Failure opening file " + path); - } - } + * DataSource_Stream Constructor + */ +DataSource_Stream::DataSource_Stream(const std::string& path, bool use_binary) + : m_identifier(path), + m_source_memory(new std::ifstream(path, use_binary ? std::ios::binary : std::ios::in)), + m_source(*m_source_memory), + m_total_read(0) { + if (!m_source.good()) { + throw Stream_IO_Error("DataSource: Failure opening file " + path); + } +} #endif /* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(std::istream& in, - const std::string& name) : - m_identifier(name), - m_source(in), - m_total_read(0) - { - } - -DataSource_Stream::~DataSource_Stream() - { - // for ~unique_ptr - } + * DataSource_Stream Constructor + */ +DataSource_Stream::DataSource_Stream(std::istream& in, const std::string& name) + : m_identifier(name), m_source(in), m_total_read(0) {} +DataSource_Stream::~DataSource_Stream() { + // for ~unique_ptr } -/* -* (C) 2017 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * (C) 2017 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -std::string to_string(ErrorType type) - { - switch(type) - { - case ErrorType::Unknown: - return "Unknown"; - case ErrorType::SystemError: - return "SystemError"; - case ErrorType::NotImplemented: - return "NotImplemented"; - case ErrorType::OutOfMemory: - return "OutOfMemory"; - case ErrorType::InternalError: - return "InternalError"; - case ErrorType::IoError: - return "IoError"; - case ErrorType::InvalidObjectState : - return "InvalidObjectState"; - case ErrorType::KeyNotSet: - return "KeyNotSet"; - case ErrorType::InvalidArgument: - return "InvalidArgument"; - case ErrorType::InvalidKeyLength: - return "InvalidKeyLength"; - case ErrorType::InvalidNonceLength: - return "InvalidNonceLength"; - case ErrorType::LookupError: - return "LookupError"; - case ErrorType::EncodingFailure: - return "EncodingFailure"; - case ErrorType::DecodingFailure: - return "DecodingFailure"; - case ErrorType::TLSError: - return "TLSError"; - case ErrorType::HttpError: - return "HttpError"; - case ErrorType::InvalidTag: - return "InvalidTag"; - case ErrorType::OpenSSLError : - return "OpenSSLError"; - case ErrorType::CommonCryptoError: - return "CommonCryptoError"; - case ErrorType::Pkcs11Error: - return "Pkcs11Error"; - case ErrorType::TPMError: - return "TPMError"; - case ErrorType::DatabaseError: - return "DatabaseError"; - case ErrorType::ZlibError : - return "ZlibError"; - case ErrorType::Bzip2Error: - return "Bzip2Error" ; - case ErrorType::LzmaError: - return "LzmaError"; - } - - // No default case in above switch so compiler warns - return "Unrecognized Botan error"; - } - -Exception::Exception(const std::string& msg) : m_msg(msg) - {} - -Exception::Exception(const std::string& msg, const std::exception& e) : - m_msg(msg + " failed with " + std::string(e.what())) - {} - -Exception::Exception(const char* prefix, const std::string& msg) : - m_msg(std::string(prefix) + " " + msg) - {} - -Invalid_Argument::Invalid_Argument(const std::string& msg) : - Exception(msg) - {} - -Invalid_Argument::Invalid_Argument(const std::string& msg, const std::string& where) : - Exception(msg + " in " + where) - {} - -Invalid_Argument::Invalid_Argument(const std::string& msg, const std::exception& e) : - Exception(msg, e) {} - -Lookup_Error::Lookup_Error(const std::string& type, - const std::string& algo, - const std::string& provider) : - Exception("Unavailable " + type + " " + algo + - (provider.empty() ? std::string("") : (" for provider " + provider))) - {} - -Internal_Error::Internal_Error(const std::string& err) : - Exception("Internal error: " + err) - {} - -Invalid_Key_Length::Invalid_Key_Length(const std::string& name, size_t length) : - Invalid_Argument(name + " cannot accept a key of length " + - std::to_string(length)) - {} - -Invalid_IV_Length::Invalid_IV_Length(const std::string& mode, size_t bad_len) : - Invalid_Argument("IV length " + std::to_string(bad_len) + - " is invalid for " + mode) - {} - -Key_Not_Set::Key_Not_Set(const std::string& algo) : - Invalid_State("Key not set in " + algo) - {} - -Policy_Violation::Policy_Violation(const std::string& err) : - Invalid_State("Policy violation: " + err) {} - -PRNG_Unseeded::PRNG_Unseeded(const std::string& algo) : - Invalid_State("PRNG not seeded: " + algo) - {} - -Algorithm_Not_Found::Algorithm_Not_Found(const std::string& name) : - Lookup_Error("Could not find any algorithm named \"" + name + "\"") - {} - -No_Provider_Found::No_Provider_Found(const std::string& name) : - Exception("Could not find any provider for algorithm named \"" + name + "\"") - {} - -Provider_Not_Found::Provider_Not_Found(const std::string& algo, const std::string& provider) : - Lookup_Error("Could not find provider '" + provider + "' for " + algo) - {} - -Invalid_Algorithm_Name::Invalid_Algorithm_Name(const std::string& name): - Invalid_Argument("Invalid algorithm name: " + name) - {} - -Encoding_Error::Encoding_Error(const std::string& name) : - Invalid_Argument("Encoding error: " + name) - {} - -Decoding_Error::Decoding_Error(const std::string& name) : - Invalid_Argument(name) - {} - -Decoding_Error::Decoding_Error(const std::string& msg, const std::exception& e) : - Invalid_Argument(msg, e) - {} - -Decoding_Error::Decoding_Error(const std::string& name, const char* exception_message) : - Invalid_Argument(name + " failed with exception " + exception_message) {} - -Invalid_Authentication_Tag::Invalid_Authentication_Tag(const std::string& msg) : - Exception("Invalid authentication tag: " + msg) - {} - -Invalid_OID::Invalid_OID(const std::string& oid) : - Decoding_Error("Invalid ASN.1 OID: " + oid) - {} - -Stream_IO_Error::Stream_IO_Error(const std::string& err) : - Exception("I/O error: " + err) - {} - -System_Error::System_Error(const std::string& msg, int err_code) : - Exception(msg + " error code " + std::to_string(err_code)), - m_error_code(err_code) - {} - -Self_Test_Failure::Self_Test_Failure(const std::string& err) : - Internal_Error("Self test failed: " + err) - {} - -Not_Implemented::Not_Implemented(const std::string& err) : - Exception("Not implemented", err) - {} +std::string to_string(ErrorType type) { + switch (type) { + case ErrorType::Unknown: + return "Unknown"; + case ErrorType::SystemError: + return "SystemError"; + case ErrorType::NotImplemented: + return "NotImplemented"; + case ErrorType::OutOfMemory: + return "OutOfMemory"; + case ErrorType::InternalError: + return "InternalError"; + case ErrorType::IoError: + return "IoError"; + case ErrorType::InvalidObjectState: + return "InvalidObjectState"; + case ErrorType::KeyNotSet: + return "KeyNotSet"; + case ErrorType::InvalidArgument: + return "InvalidArgument"; + case ErrorType::InvalidKeyLength: + return "InvalidKeyLength"; + case ErrorType::InvalidNonceLength: + return "InvalidNonceLength"; + case ErrorType::LookupError: + return "LookupError"; + case ErrorType::EncodingFailure: + return "EncodingFailure"; + case ErrorType::DecodingFailure: + return "DecodingFailure"; + case ErrorType::TLSError: + return "TLSError"; + case ErrorType::HttpError: + return "HttpError"; + case ErrorType::InvalidTag: + return "InvalidTag"; + case ErrorType::OpenSSLError: + return "OpenSSLError"; + case ErrorType::CommonCryptoError: + return "CommonCryptoError"; + case ErrorType::Pkcs11Error: + return "Pkcs11Error"; + case ErrorType::TPMError: + return "TPMError"; + case ErrorType::DatabaseError: + return "DatabaseError"; + case ErrorType::ZlibError: + return "ZlibError"; + case ErrorType::Bzip2Error: + return "Bzip2Error"; + case ErrorType::LzmaError: + return "LzmaError"; + } + // No default case in above switch so compiler warns + return "Unrecognized Botan error"; } -/* -* (C) 2015,2017,2019 Jack Lloyd -* (C) 2015 Simon Warta (Kullo GmbH) -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +Exception::Exception(const std::string& msg) : m_msg(msg) {} + +Exception::Exception(const std::string& msg, const std::exception& e) + : m_msg(msg + " failed with " + std::string(e.what())) {} + +Exception::Exception(const char* prefix, const std::string& msg) + : m_msg(std::string(prefix) + " " + msg) {} + +Invalid_Argument::Invalid_Argument(const std::string& msg) : Exception(msg) {} + +Invalid_Argument::Invalid_Argument(const std::string& msg, const std::string& where) + : Exception(msg + " in " + where) {} + +Invalid_Argument::Invalid_Argument(const std::string& msg, const std::exception& e) + : Exception(msg, e) {} + +Lookup_Error::Lookup_Error(const std::string& type, const std::string& algo, + const std::string& provider) + : Exception("Unavailable " + type + " " + algo + + (provider.empty() ? std::string("") : (" for provider " + provider))) {} + +Internal_Error::Internal_Error(const std::string& err) : Exception("Internal error: " + err) {} + +Invalid_Key_Length::Invalid_Key_Length(const std::string& name, size_t length) + : Invalid_Argument(name + " cannot accept a key of length " + std::to_string(length)) {} + +Invalid_IV_Length::Invalid_IV_Length(const std::string& mode, size_t bad_len) + : Invalid_Argument("IV length " + std::to_string(bad_len) + " is invalid for " + mode) {} + +Key_Not_Set::Key_Not_Set(const std::string& algo) : Invalid_State("Key not set in " + algo) {} + +Policy_Violation::Policy_Violation(const std::string& err) + : Invalid_State("Policy violation: " + err) {} + +PRNG_Unseeded::PRNG_Unseeded(const std::string& algo) : Invalid_State("PRNG not seeded: " + algo) {} + +Algorithm_Not_Found::Algorithm_Not_Found(const std::string& name) + : Lookup_Error("Could not find any algorithm named \"" + name + "\"") {} + +No_Provider_Found::No_Provider_Found(const std::string& name) + : Exception("Could not find any provider for algorithm named \"" + name + "\"") {} + +Provider_Not_Found::Provider_Not_Found(const std::string& algo, const std::string& provider) + : Lookup_Error("Could not find provider '" + provider + "' for " + algo) {} + +Invalid_Algorithm_Name::Invalid_Algorithm_Name(const std::string& name) + : Invalid_Argument("Invalid algorithm name: " + name) {} + +Encoding_Error::Encoding_Error(const std::string& name) + : Invalid_Argument("Encoding error: " + name) {} + +Decoding_Error::Decoding_Error(const std::string& name) : Invalid_Argument(name) {} + +Decoding_Error::Decoding_Error(const std::string& msg, const std::exception& e) + : Invalid_Argument(msg, e) {} + +Decoding_Error::Decoding_Error(const std::string& name, const char* exception_message) + : Invalid_Argument(name + " failed with exception " + exception_message) {} + +Invalid_Authentication_Tag::Invalid_Authentication_Tag(const std::string& msg) + : Exception("Invalid authentication tag: " + msg) {} + +Invalid_OID::Invalid_OID(const std::string& oid) : Decoding_Error("Invalid ASN.1 OID: " + oid) {} + +Stream_IO_Error::Stream_IO_Error(const std::string& err) : Exception("I/O error: " + err) {} + +System_Error::System_Error(const std::string& msg, int err_code) + : Exception(msg + " error code " + std::to_string(err_code)), m_error_code(err_code) {} + +Self_Test_Failure::Self_Test_Failure(const std::string& err) + : Internal_Error("Self test failed: " + err) {} + +Not_Implemented::Not_Implemented(const std::string& err) : Exception("Not implemented", err) {} + +} // namespace Botan +/* + * (C) 2015,2017,2019 Jack Lloyd + * (C) 2015 Simon Warta (Kullo GmbH) + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - #include - #include - #include +#include +#include +#include #elif defined(BOTAN_TARGET_OS_HAS_WIN32) - #define NOMINMAX 1 - #define _WINSOCKAPI_ // stop windows.h including winsock.h - #include +#define NOMINMAX 1 +#define _WINSOCKAPI_ // stop windows.h including winsock.h +#include #endif namespace Botan { @@ -24977,125 +22384,108 @@ namespace { #if defined(BOTAN_TARGET_OS_HAS_POSIX1) -std::vector impl_readdir(const std::string& dir_path) - { - std::vector out; - std::deque dir_list; - dir_list.push_back(dir_path); +std::vector impl_readdir(const std::string& dir_path) { + std::vector out; + std::deque dir_list; + dir_list.push_back(dir_path); - while(!dir_list.empty()) - { - const std::string cur_path = dir_list[0]; - dir_list.pop_front(); + while (!dir_list.empty()) { + const std::string cur_path = dir_list[0]; + dir_list.pop_front(); - std::unique_ptr> dir(::opendir(cur_path.c_str()), ::closedir); + std::unique_ptr> dir(::opendir(cur_path.c_str()), ::closedir); - if(dir) - { - while(struct dirent* dirent = ::readdir(dir.get())) - { - const std::string filename = dirent->d_name; - if(filename == "." || filename == "..") - continue; - const std::string full_path = cur_path + "/" + filename; + if (dir) { + while (struct dirent* dirent = ::readdir(dir.get())) { + const std::string filename = dirent->d_name; + if (filename == "." || filename == "..") continue; + const std::string full_path = cur_path + "/" + filename; - struct stat stat_buf; + struct stat stat_buf; - if(::stat(full_path.c_str(), &stat_buf) == -1) - continue; + if (::stat(full_path.c_str(), &stat_buf) == -1) continue; - if(S_ISDIR(stat_buf.st_mode)) - dir_list.push_back(full_path); - else if(S_ISREG(stat_buf.st_mode)) - out.push_back(full_path); + if (S_ISDIR(stat_buf.st_mode)) + dir_list.push_back(full_path); + else if (S_ISREG(stat_buf.st_mode)) + out.push_back(full_path); } - } - } + } + } - return out; - } + return out; +} #elif defined(BOTAN_TARGET_OS_HAS_WIN32) -std::vector impl_win32(const std::string& dir_path) - { - std::vector out; - std::deque dir_list; - dir_list.push_back(dir_path); +std::vector impl_win32(const std::string& dir_path) { + std::vector out; + std::deque dir_list; + dir_list.push_back(dir_path); - while(!dir_list.empty()) - { - const std::string cur_path = dir_list[0]; - dir_list.pop_front(); + while (!dir_list.empty()) { + const std::string cur_path = dir_list[0]; + dir_list.pop_front(); - WIN32_FIND_DATAA find_data; - HANDLE dir = ::FindFirstFileA((cur_path + "/*").c_str(), &find_data); + WIN32_FIND_DATAA find_data; + HANDLE dir = ::FindFirstFileA((cur_path + "/*").c_str(), &find_data); - if(dir != INVALID_HANDLE_VALUE) - { - do - { - const std::string filename = find_data.cFileName; - if(filename == "." || filename == "..") - continue; - const std::string full_path = cur_path + "/" + filename; + if (dir != INVALID_HANDLE_VALUE) { + do { + const std::string filename = find_data.cFileName; + if (filename == "." || filename == "..") continue; + const std::string full_path = cur_path + "/" + filename; - if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - dir_list.push_back(full_path); - } - else - { - out.push_back(full_path); - } - } - while(::FindNextFileA(dir, &find_data)); - } + if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + dir_list.push_back(full_path); + } else { + out.push_back(full_path); + } + } while (::FindNextFileA(dir, &find_data)); + } - ::FindClose(dir); - } + ::FindClose(dir); + } - return out; + return out; } #endif -} +} // namespace -bool has_filesystem_impl() - { +bool has_filesystem_impl() { #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - return true; + return true; #elif defined(BOTAN_TARGET_OS_HAS_WIN32) - return true; + return true; #else - return false; + return false; #endif - } +} -std::vector get_files_recursive(const std::string& dir) - { - std::vector files; +std::vector get_files_recursive(const std::string& dir) { + std::vector files; #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - files = impl_readdir(dir); + files = impl_readdir(dir); #elif defined(BOTAN_TARGET_OS_HAS_WIN32) - files = impl_win32(dir); + files = impl_win32(dir); #else - BOTAN_UNUSED(dir); - throw No_Filesystem_Access(); + BOTAN_UNUSED(dir); + throw No_Filesystem_Access(); #endif - std::sort(files.begin(), files.end()); - - return files; - } + std::sort(files.begin(), files.end()); + return files; } + +} // namespace Botan /* -* (C) 2017 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * (C) 2017 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #include #include @@ -25105,619 +22495,560 @@ std::vector get_files_recursive(const std::string& dir) namespace Botan { -BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t elem_size) - { - if(elems == 0 || elem_size == 0) - return nullptr; +BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t elem_size) { + if (elems == 0 || elem_size == 0) return nullptr; #if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - if(void* p = mlock_allocator::instance().allocate(elems, elem_size)) - return p; + if (void* p = mlock_allocator::instance().allocate(elems, elem_size)) return p; #endif - void* ptr = std::calloc(elems, elem_size); - if(!ptr) - throw std::bad_alloc(); - return ptr; - } - -void deallocate_memory(void* p, size_t elems, size_t elem_size) - { - if(p == nullptr) - return; - - secure_scrub_memory(p, elems * elem_size); - -#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - if(mlock_allocator::instance().deallocate(p, elems, elem_size)) - return; -#endif - - std::free(p); - } - -void initialize_allocator() - { -#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - mlock_allocator::instance(); -#endif - } - -uint8_t ct_compare_u8(const uint8_t x[], - const uint8_t y[], - size_t len) - { - volatile uint8_t difference = 0; - - for(size_t i = 0; i != len; ++i) - difference |= (x[i] ^ y[i]); - - return CT::Mask::is_zero(difference).value(); - } - + void* ptr = std::calloc(elems, elem_size); + if (!ptr) throw std::bad_alloc(); + return ptr; } + +void deallocate_memory(void* p, size_t elems, size_t elem_size) { + if (p == nullptr) return; + + secure_scrub_memory(p, elems * elem_size); + +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + if (mlock_allocator::instance().deallocate(p, elems, elem_size)) return; +#endif + + std::free(p); +} + +void initialize_allocator() { +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + mlock_allocator::instance(); +#endif +} + +uint8_t ct_compare_u8(const uint8_t x[], const uint8_t y[], size_t len) { + volatile uint8_t difference = 0; + + for (size_t i = 0; i != len; ++i) difference |= (x[i] ^ y[i]); + + return CT::Mask::is_zero(difference).value(); +} + +} // namespace Botan /* -* OS and machine specific utility functions -* (C) 2015,2016,2017,2018 Jack Lloyd -* (C) 2016 Daniel Neus -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - - + * OS and machine specific utility functions + * (C) 2015,2016,2017,2018 Jack Lloyd + * (C) 2016 Daniel Neus + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #if defined(BOTAN_TARGET_OS_HAS_THREADS) - #include +#include #endif #if defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO) - #include +#include #endif #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - #include - #include - #include - #include - #include - #include - #include - #include - #undef B0 +#include +#include +#include +#include +#include +#include +#include +#include +#undef B0 #endif #if defined(BOTAN_TARGET_OS_IS_EMSCRIPTEN) - #include +#include #endif #if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) || defined(BOTAN_TARGET_OS_IS_ANDROID) || \ - defined(BOTAN_TARGET_OS_HAS_ELF_AUX_INFO) - #include + defined(BOTAN_TARGET_OS_HAS_ELF_AUX_INFO) +#include #endif #if defined(BOTAN_TARGET_OS_HAS_WIN32) - #define NOMINMAX 1 - #include +#define NOMINMAX 1 +#include #endif #if defined(BOTAN_TARGET_OS_IS_ANDROID) - #include - extern "C" char **environ; +#include +extern "C" char** environ; #endif #if defined(BOTAN_TARGET_OS_IS_IOS) || defined(BOTAN_TARGET_OS_IS_MACOS) - #include +#include #endif namespace Botan { // Not defined in OS namespace for historical reasons -void secure_scrub_memory(void* ptr, size_t n) - { +void secure_scrub_memory(void* ptr, size_t n) { #if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY) - ::RtlSecureZeroMemory(ptr, n); + ::RtlSecureZeroMemory(ptr, n); #elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO) - ::explicit_bzero(ptr, n); + ::explicit_bzero(ptr, n); #elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_MEMSET) - (void)::explicit_memset(ptr, 0, n); + (void)::explicit_memset(ptr, 0, n); #elif defined(BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO) && (BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO == 1) - /* - Call memset through a static volatile pointer, which the compiler - should not elide. This construct should be safe in conforming - compilers, but who knows. I did confirm that on x86-64 GCC 6.1 and - Clang 3.8 both create code that saves the memset address in the - data segment and unconditionally loads and jumps to that address. - */ - static void* (*const volatile memset_ptr)(void*, int, size_t) = std::memset; - (memset_ptr)(ptr, 0, n); + /* + Call memset through a static volatile pointer, which the compiler + should not elide. This construct should be safe in conforming + compilers, but who knows. I did confirm that on x86-64 GCC 6.1 and + Clang 3.8 both create code that saves the memset address in the + data segment and unconditionally loads and jumps to that address. + */ + static void* (*const volatile memset_ptr)(void*, int, size_t) = std::memset; + (memset_ptr)(ptr, 0, n); #else - volatile uint8_t* p = reinterpret_cast(ptr); + volatile uint8_t* p = reinterpret_cast(ptr); - for(size_t i = 0; i != n; ++i) - p[i] = 0; + for (size_t i = 0; i != n; ++i) p[i] = 0; #endif - } +} -uint32_t OS::get_process_id() - { +uint32_t OS::get_process_id() { #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - return ::getpid(); + return ::getpid(); #elif defined(BOTAN_TARGET_OS_HAS_WIN32) - return ::GetCurrentProcessId(); + return ::GetCurrentProcessId(); #elif defined(BOTAN_TARGET_OS_IS_INCLUDEOS) || defined(BOTAN_TARGET_OS_IS_LLVM) - return 0; // truly no meaningful value + return 0; // truly no meaningful value #else - #error "Missing get_process_id" +#error "Missing get_process_id" #endif - } +} -unsigned long OS::get_auxval(unsigned long id) - { +unsigned long OS::get_auxval(unsigned long id) { #if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) - return ::getauxval(id); + return ::getauxval(id); #elif defined(BOTAN_TARGET_OS_IS_ANDROID) && defined(BOTAN_TARGET_ARCH_IS_ARM32) - if(id == 0) - return 0; + if (id == 0) return 0; - char **p = environ; + char** p = environ; - while(*p++ != nullptr) - ; + while (*p++ != nullptr); - Elf32_auxv_t *e = reinterpret_cast(p); + Elf32_auxv_t* e = reinterpret_cast(p); - while(e != nullptr) - { - if(e->a_type == id) - return e->a_un.a_val; - e++; - } + while (e != nullptr) { + if (e->a_type == id) return e->a_un.a_val; + e++; + } - return 0; + return 0; #elif defined(BOTAN_TARGET_OS_HAS_ELF_AUX_INFO) - unsigned long auxinfo = 0; - ::elf_aux_info(id, &auxinfo, sizeof(auxinfo)); - return auxinfo; + unsigned long auxinfo = 0; + ::elf_aux_info(id, &auxinfo, sizeof(auxinfo)); + return auxinfo; #else - BOTAN_UNUSED(id); - return 0; + BOTAN_UNUSED(id); + return 0; #endif - } +} -bool OS::running_in_privileged_state() - { +bool OS::running_in_privileged_state() { #if defined(AT_SECURE) - return OS::get_auxval(AT_SECURE) != 0; + return OS::get_auxval(AT_SECURE) != 0; #elif defined(BOTAN_TARGET_OS_HAS_POSIX1) - return (::getuid() != ::geteuid()) || (::getgid() != ::getegid()); + return (::getuid() != ::geteuid()) || (::getgid() != ::getegid()); #else - return false; + return false; #endif - } +} -uint64_t OS::get_cpu_cycle_counter() - { - uint64_t rtc = 0; +uint64_t OS::get_cpu_cycle_counter() { + uint64_t rtc = 0; #if defined(BOTAN_TARGET_OS_HAS_WIN32) - LARGE_INTEGER tv; - ::QueryPerformanceCounter(&tv); - rtc = tv.QuadPart; + LARGE_INTEGER tv; + ::QueryPerformanceCounter(&tv); + rtc = tv.QuadPart; #elif defined(BOTAN_USE_GCC_INLINE_ASM) #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - if(CPUID::has_rdtsc()) - { - uint32_t rtc_low = 0, rtc_high = 0; - asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low)); - rtc = (static_cast(rtc_high) << 32) | rtc_low; - } + if (CPUID::has_rdtsc()) { + uint32_t rtc_low = 0, rtc_high = 0; + asm volatile("rdtsc" : "=d"(rtc_high), "=a"(rtc_low)); + rtc = (static_cast(rtc_high) << 32) | rtc_low; + } #elif defined(BOTAN_TARGET_ARCH_IS_PPC64) - for(;;) - { - uint32_t rtc_low = 0, rtc_high = 0, rtc_high2 = 0; - asm volatile("mftbu %0" : "=r" (rtc_high)); - asm volatile("mftb %0" : "=r" (rtc_low)); - asm volatile("mftbu %0" : "=r" (rtc_high2)); + for (;;) { + uint32_t rtc_low = 0, rtc_high = 0, rtc_high2 = 0; + asm volatile("mftbu %0" : "=r"(rtc_high)); + asm volatile("mftb %0" : "=r"(rtc_low)); + asm volatile("mftbu %0" : "=r"(rtc_high2)); - if(rtc_high == rtc_high2) - { - rtc = (static_cast(rtc_high) << 32) | rtc_low; - break; - } - } + if (rtc_high == rtc_high2) { + rtc = (static_cast(rtc_high) << 32) | rtc_low; + break; + } + } #elif defined(BOTAN_TARGET_ARCH_IS_ALPHA) - asm volatile("rpcc %0" : "=r" (rtc)); + asm volatile("rpcc %0" : "=r"(rtc)); - // OpenBSD does not trap access to the %tick register + // OpenBSD does not trap access to the %tick register #elif defined(BOTAN_TARGET_ARCH_IS_SPARC64) && !defined(BOTAN_TARGET_OS_IS_OPENBSD) - asm volatile("rd %%tick, %0" : "=r" (rtc)); + asm volatile("rd %%tick, %0" : "=r"(rtc)); #elif defined(BOTAN_TARGET_ARCH_IS_IA64) - asm volatile("mov %0=ar.itc" : "=r" (rtc)); + asm volatile("mov %0=ar.itc" : "=r"(rtc)); #elif defined(BOTAN_TARGET_ARCH_IS_S390X) - asm volatile("stck 0(%0)" : : "a" (&rtc) : "memory", "cc"); + asm volatile("stck 0(%0)" : : "a"(&rtc) : "memory", "cc"); #elif defined(BOTAN_TARGET_ARCH_IS_HPPA) - asm volatile("mfctl 16,%0" : "=r" (rtc)); // 64-bit only? + asm volatile("mfctl 16,%0" : "=r"(rtc)); // 64-bit only? #else - //#warning "OS::get_cpu_cycle_counter not implemented" + // #warning "OS::get_cpu_cycle_counter not implemented" #endif #endif - return rtc; - } + return rtc; +} -size_t OS::get_cpu_total() - { +size_t OS::get_cpu_total() { #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(_SC_NPROCESSORS_CONF) - const long res = ::sysconf(_SC_NPROCESSORS_CONF); - if(res > 0) - return static_cast(res); + const long res = ::sysconf(_SC_NPROCESSORS_CONF); + if (res > 0) return static_cast(res); #endif #if defined(BOTAN_TARGET_OS_HAS_THREADS) - return static_cast(std::thread::hardware_concurrency()); + return static_cast(std::thread::hardware_concurrency()); #else - return 1; + return 1; #endif - } +} -size_t OS::get_cpu_available() - { +size_t OS::get_cpu_available() { #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(_SC_NPROCESSORS_ONLN) - const long res = ::sysconf(_SC_NPROCESSORS_ONLN); - if(res > 0) - return static_cast(res); + const long res = ::sysconf(_SC_NPROCESSORS_ONLN); + if (res > 0) return static_cast(res); #endif - return OS::get_cpu_total(); - } + return OS::get_cpu_total(); +} -uint64_t OS::get_high_resolution_clock() - { - if(uint64_t cpu_clock = OS::get_cpu_cycle_counter()) - return cpu_clock; +uint64_t OS::get_high_resolution_clock() { + if (uint64_t cpu_clock = OS::get_cpu_cycle_counter()) return cpu_clock; #if defined(BOTAN_TARGET_OS_IS_EMSCRIPTEN) - return emscripten_get_now(); + return emscripten_get_now(); #endif - /* - If we got here either we either don't have an asm instruction - above, or (for x86) RDTSC is not available at runtime. Try some - clock_gettimes and return the first one that works, or otherwise - fall back to std::chrono. - */ + /* + If we got here either we either don't have an asm instruction + above, or (for x86) RDTSC is not available at runtime. Try some + clock_gettimes and return the first one that works, or otherwise + fall back to std::chrono. + */ #if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) - // The ordering here is somewhat arbitrary... - const clockid_t clock_types[] = { + // The ordering here is somewhat arbitrary... + const clockid_t clock_types[] = { #if defined(CLOCK_MONOTONIC_HR) - CLOCK_MONOTONIC_HR, + CLOCK_MONOTONIC_HR, #endif #if defined(CLOCK_MONOTONIC_RAW) - CLOCK_MONOTONIC_RAW, + CLOCK_MONOTONIC_RAW, #endif #if defined(CLOCK_MONOTONIC) - CLOCK_MONOTONIC, + CLOCK_MONOTONIC, #endif #if defined(CLOCK_PROCESS_CPUTIME_ID) - CLOCK_PROCESS_CPUTIME_ID, + CLOCK_PROCESS_CPUTIME_ID, #endif #if defined(CLOCK_THREAD_CPUTIME_ID) - CLOCK_THREAD_CPUTIME_ID, + CLOCK_THREAD_CPUTIME_ID, #endif - }; + }; - for(clockid_t clock : clock_types) - { - struct timespec ts; - if(::clock_gettime(clock, &ts) == 0) - { - return (static_cast(ts.tv_sec) * 1000000000) + static_cast(ts.tv_nsec); - } - } + for (clockid_t clock : clock_types) { + struct timespec ts; + if (::clock_gettime(clock, &ts) == 0) { + return (static_cast(ts.tv_sec) * 1000000000) + + static_cast(ts.tv_nsec); + } + } #endif - // Plain C++11 fallback - auto now = std::chrono::high_resolution_clock::now().time_since_epoch(); - return std::chrono::duration_cast(now).count(); - } + // Plain C++11 fallback + auto now = std::chrono::high_resolution_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); +} -uint64_t OS::get_system_timestamp_ns() - { +uint64_t OS::get_system_timestamp_ns() { #if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) - struct timespec ts; - if(::clock_gettime(CLOCK_REALTIME, &ts) == 0) - { - return (static_cast(ts.tv_sec) * 1000000000) + static_cast(ts.tv_nsec); - } + struct timespec ts; + if (::clock_gettime(CLOCK_REALTIME, &ts) == 0) { + return (static_cast(ts.tv_sec) * 1000000000) + static_cast(ts.tv_nsec); + } #endif - auto now = std::chrono::system_clock::now().time_since_epoch(); - return std::chrono::duration_cast(now).count(); - } + auto now = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); +} -size_t OS::system_page_size() - { - const size_t default_page_size = 4096; +size_t OS::system_page_size() { + const size_t default_page_size = 4096; #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - long p = ::sysconf(_SC_PAGESIZE); - if(p > 1) - return static_cast(p); - else - return default_page_size; + long p = ::sysconf(_SC_PAGESIZE); + if (p > 1) + return static_cast(p); + else + return default_page_size; #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) - SYSTEM_INFO sys_info; - ::GetSystemInfo(&sys_info); - return sys_info.dwPageSize; + SYSTEM_INFO sys_info; + ::GetSystemInfo(&sys_info); + return sys_info.dwPageSize; #else - return default_page_size; + return default_page_size; #endif - } +} -size_t OS::get_memory_locking_limit() - { -#if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) && defined(RLIMIT_MEMLOCK) - /* - * If RLIMIT_MEMLOCK is not defined, likely the OS does not support - * unprivileged mlock calls. - * - * Linux defaults to only 64 KiB of mlockable memory per process - * (too small) but BSDs offer a small fraction of total RAM (more - * than we need). Bound the total mlock size to 512 KiB which is - * enough to run the entire test suite without spilling to non-mlock - * memory (and thus presumably also enough for many useful - * programs), but small enough that we should not cause problems - * even if many processes are mlocking on the same machine. - */ - const size_t user_req = read_env_variable_sz("BOTAN_MLOCK_POOL_SIZE", BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB); +size_t OS::get_memory_locking_limit() { +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) && \ + defined(RLIMIT_MEMLOCK) + /* + * If RLIMIT_MEMLOCK is not defined, likely the OS does not support + * unprivileged mlock calls. + * + * Linux defaults to only 64 KiB of mlockable memory per process + * (too small) but BSDs offer a small fraction of total RAM (more + * than we need). Bound the total mlock size to 512 KiB which is + * enough to run the entire test suite without spilling to non-mlock + * memory (and thus presumably also enough for many useful + * programs), but small enough that we should not cause problems + * even if many processes are mlocking on the same machine. + */ + const size_t user_req = + read_env_variable_sz("BOTAN_MLOCK_POOL_SIZE", BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB); - const size_t mlock_requested = std::min(user_req, BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB); + const size_t mlock_requested = std::min(user_req, BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB); - if(mlock_requested > 0) - { - struct ::rlimit limits; + if (mlock_requested > 0) { + struct ::rlimit limits; - ::getrlimit(RLIMIT_MEMLOCK, &limits); + ::getrlimit(RLIMIT_MEMLOCK, &limits); - if(limits.rlim_cur < limits.rlim_max) - { - limits.rlim_cur = limits.rlim_max; - ::setrlimit(RLIMIT_MEMLOCK, &limits); - ::getrlimit(RLIMIT_MEMLOCK, &limits); - } + if (limits.rlim_cur < limits.rlim_max) { + limits.rlim_cur = limits.rlim_max; + ::setrlimit(RLIMIT_MEMLOCK, &limits); + ::getrlimit(RLIMIT_MEMLOCK, &limits); + } - return std::min(limits.rlim_cur, mlock_requested * 1024); - } + return std::min(limits.rlim_cur, mlock_requested * 1024); + } #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) - SIZE_T working_min = 0, working_max = 0; - if(!::GetProcessWorkingSetSize(::GetCurrentProcess(), &working_min, &working_max)) - { - return 0; - } + SIZE_T working_min = 0, working_max = 0; + if (!::GetProcessWorkingSetSize(::GetCurrentProcess(), &working_min, &working_max)) { + return 0; + } - // According to Microsoft MSDN: - // The maximum number of pages that a process can lock is equal to the number of pages in its minimum working set minus a small overhead - // In the book "Windows Internals Part 2": the maximum lockable pages are minimum working set size - 8 pages - // But the information in the book seems to be inaccurate/outdated - // I've tested this on Windows 8.1 x64, Windows 10 x64 and Windows 7 x86 - // On all three OS the value is 11 instead of 8 - const size_t overhead = OS::system_page_size() * 11; - if(working_min > overhead) - { - const size_t lockable_bytes = working_min - overhead; - return std::min(lockable_bytes, BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB * 1024); - } + // According to Microsoft MSDN: + // The maximum number of pages that a process can lock is equal to the number of pages in its + // minimum working set minus a small overhead In the book "Windows Internals Part 2": the + // maximum lockable pages are minimum working set size - 8 pages But the information in the book + // seems to be inaccurate/outdated I've tested this on Windows 8.1 x64, Windows 10 x64 and + // Windows 7 x86 On all three OS the value is 11 instead of 8 + const size_t overhead = OS::system_page_size() * 11; + if (working_min > overhead) { + const size_t lockable_bytes = working_min - overhead; + return std::min(lockable_bytes, BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB * 1024); + } #endif - // Not supported on this platform - return 0; - } + // Not supported on this platform + return 0; +} -const char* OS::read_env_variable(const std::string& name) - { - if(running_in_privileged_state()) - return nullptr; +const char* OS::read_env_variable(const std::string& name) { + if (running_in_privileged_state()) return nullptr; - return std::getenv(name.c_str()); - } + return std::getenv(name.c_str()); +} -size_t OS::read_env_variable_sz(const std::string& name, size_t def) - { - if(const char* env = read_env_variable(name)) - { - try - { - const size_t val = std::stoul(env, nullptr); - return val; - } - catch(std::exception&) { /* ignore it */ } - } +size_t OS::read_env_variable_sz(const std::string& name, size_t def) { + if (const char* env = read_env_variable(name)) { + try { + const size_t val = std::stoul(env, nullptr); + return val; + } catch (std::exception&) { /* ignore it */ + } + } - return def; - } + return def; +} #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) namespace { -int get_locked_fd() - { +int get_locked_fd() { #if defined(BOTAN_TARGET_OS_IS_IOS) || defined(BOTAN_TARGET_OS_IS_MACOS) - // On Darwin, tagging anonymous pages allows vmmap to track these. - // Allowed from 240 to 255 for userland applications - static constexpr int default_locked_fd = 255; - int locked_fd = default_locked_fd; + // On Darwin, tagging anonymous pages allows vmmap to track these. + // Allowed from 240 to 255 for userland applications + static constexpr int default_locked_fd = 255; + int locked_fd = default_locked_fd; - if(size_t locked_fdl = OS::read_env_variable_sz("BOTAN_LOCKED_FD", default_locked_fd)) - { - if(locked_fdl < 240 || locked_fdl > 255) - { - locked_fdl = default_locked_fd; - } - locked_fd = static_cast(locked_fdl); - } - return VM_MAKE_TAG(locked_fd); + if (size_t locked_fdl = OS::read_env_variable_sz("BOTAN_LOCKED_FD", default_locked_fd)) { + if (locked_fdl < 240 || locked_fdl > 255) { + locked_fdl = default_locked_fd; + } + locked_fd = static_cast(locked_fdl); + } + return VM_MAKE_TAG(locked_fd); #else - return -1; + return -1; #endif - } - } +} // namespace + #endif -std::vector OS::allocate_locked_pages(size_t count) - { +std::vector OS::allocate_locked_pages(size_t count) { #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) - static const int locked_fd = get_locked_fd(); + static const int locked_fd = get_locked_fd(); #endif - std::vector result; - result.reserve(count); + std::vector result; + result.reserve(count); - const size_t page_size = OS::system_page_size(); + const size_t page_size = OS::system_page_size(); - for(size_t i = 0; i != count; ++i) - { - void* ptr = nullptr; + for (size_t i = 0; i != count; ++i) { + void* ptr = nullptr; #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) #if !defined(MAP_ANONYMOUS) - #define MAP_ANONYMOUS MAP_ANON +#define MAP_ANONYMOUS MAP_ANON #endif #if !defined(MAP_NOCORE) #if defined(MAP_CONCEAL) - #define MAP_NOCORE MAP_CONCEAL +#define MAP_NOCORE MAP_CONCEAL #else - #define MAP_NOCORE 0 +#define MAP_NOCORE 0 #endif #endif #if !defined(PROT_MAX) - #define PROT_MAX(p) 0 +#define PROT_MAX(p) 0 #endif - const int pflags = PROT_READ | PROT_WRITE; + const int pflags = PROT_READ | PROT_WRITE; - ptr = ::mmap(nullptr, 2*page_size, - pflags | PROT_MAX(pflags), - MAP_ANONYMOUS | MAP_PRIVATE | MAP_NOCORE, - /*fd=*/locked_fd, /*offset=*/0); + ptr = ::mmap(nullptr, 2 * page_size, pflags | PROT_MAX(pflags), + MAP_ANONYMOUS | MAP_PRIVATE | MAP_NOCORE, + /*fd=*/locked_fd, /*offset=*/0); - if(ptr == MAP_FAILED) - { - continue; - } + if (ptr == MAP_FAILED) { + continue; + } - // failed to lock - if(::mlock(ptr, page_size) != 0) - { - ::munmap(ptr, 2*page_size); - continue; - } + // failed to lock + if (::mlock(ptr, page_size) != 0) { + ::munmap(ptr, 2 * page_size); + continue; + } #if defined(MADV_DONTDUMP) - // we ignore errors here, as DONTDUMP is just a bonus - ::madvise(ptr, page_size, MADV_DONTDUMP); + // we ignore errors here, as DONTDUMP is just a bonus + ::madvise(ptr, page_size, MADV_DONTDUMP); #endif #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) - ptr = ::VirtualAlloc(nullptr, 2*page_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + ptr = ::VirtualAlloc(nullptr, 2 * page_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if(ptr == nullptr) - continue; + if (ptr == nullptr) continue; - if(::VirtualLock(ptr, page_size) == 0) - { - ::VirtualFree(ptr, 0, MEM_RELEASE); - continue; - } + if (::VirtualLock(ptr, page_size) == 0) { + ::VirtualFree(ptr, 0, MEM_RELEASE); + continue; + } #endif - std::memset(ptr, 0, 2*page_size); // zero both data and guard pages + std::memset(ptr, 0, 2 * page_size); // zero both data and guard pages - // Make guard page following the data page - page_prohibit_access(static_cast(ptr) + page_size); + // Make guard page following the data page + page_prohibit_access(static_cast(ptr) + page_size); - result.push_back(ptr); - } + result.push_back(ptr); + } - return result; - } + return result; +} -void OS::page_allow_access(void* page) - { - const size_t page_size = OS::system_page_size(); - (void)page_size; - (void)page; +void OS::page_allow_access(void* page) { + const size_t page_size = OS::system_page_size(); + (void)page_size; + (void)page; #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - ::mprotect(page, page_size, PROT_READ | PROT_WRITE); + ::mprotect(page, page_size, PROT_READ | PROT_WRITE); #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) - DWORD old_perms = 0; - ::VirtualProtect(page, page_size, PAGE_READWRITE, &old_perms); - BOTAN_UNUSED(old_perms); - BOTAN_UNUSED(page); - BOTAN_UNUSED(page_size); + DWORD old_perms = 0; + ::VirtualProtect(page, page_size, PAGE_READWRITE, &old_perms); + BOTAN_UNUSED(old_perms); + BOTAN_UNUSED(page); + BOTAN_UNUSED(page_size); #endif - } +} -void OS::page_prohibit_access(void* page) - { - const size_t page_size = OS::system_page_size(); - (void)page_size; - (void)page; +void OS::page_prohibit_access(void* page) { + const size_t page_size = OS::system_page_size(); + (void)page_size; + (void)page; #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - ::mprotect(page, page_size, PROT_NONE); + ::mprotect(page, page_size, PROT_NONE); #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) - DWORD old_perms = 0; - ::VirtualProtect(page, page_size, PAGE_NOACCESS, &old_perms); - BOTAN_UNUSED(old_perms); + DWORD old_perms = 0; + ::VirtualProtect(page, page_size, PAGE_NOACCESS, &old_perms); + BOTAN_UNUSED(old_perms); #endif - } +} -void OS::free_locked_pages(const std::vector& pages) - { - const size_t page_size = OS::system_page_size(); +void OS::free_locked_pages(const std::vector& pages) { + const size_t page_size = OS::system_page_size(); - for(size_t i = 0; i != pages.size(); ++i) - { - void* ptr = pages[i]; + for (size_t i = 0; i != pages.size(); ++i) { + void* ptr = pages[i]; - secure_scrub_memory(ptr, page_size); + secure_scrub_memory(ptr, page_size); - // ptr points to the data page, guard page follows - page_allow_access(static_cast(ptr) + page_size); + // ptr points to the data page, guard page follows + page_allow_access(static_cast(ptr) + page_size); #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) - ::munlock(ptr, page_size); - ::munmap(ptr, 2*page_size); + ::munlock(ptr, page_size); + ::munmap(ptr, 2 * page_size); #elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) - ::VirtualUnlock(ptr, page_size); - ::VirtualFree(ptr, 0, MEM_RELEASE); + ::VirtualUnlock(ptr, page_size); + ::VirtualFree(ptr, 0, MEM_RELEASE); #endif - } - } + } +} #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && !defined(BOTAN_TARGET_OS_IS_EMSCRIPTEN) @@ -25725,178 +23056,149 @@ namespace { static ::sigjmp_buf g_sigill_jmp_buf; -void botan_sigill_handler(int) - { - siglongjmp(g_sigill_jmp_buf, /*non-zero return value*/1); - } +void botan_sigill_handler(int) { siglongjmp(g_sigill_jmp_buf, /*non-zero return value*/ 1); } -} +} // namespace #endif -int OS::run_cpu_instruction_probe(std::function probe_fn) - { - volatile int probe_result = -3; +int OS::run_cpu_instruction_probe(std::function probe_fn) { + volatile int probe_result = -3; #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && !defined(BOTAN_TARGET_OS_IS_EMSCRIPTEN) - struct sigaction old_sigaction; - struct sigaction sigaction; + struct sigaction old_sigaction; + struct sigaction sigaction; - sigaction.sa_handler = botan_sigill_handler; - sigemptyset(&sigaction.sa_mask); - sigaction.sa_flags = 0; + sigaction.sa_handler = botan_sigill_handler; + sigemptyset(&sigaction.sa_mask); + sigaction.sa_flags = 0; - int rc = ::sigaction(SIGILL, &sigaction, &old_sigaction); + int rc = ::sigaction(SIGILL, &sigaction, &old_sigaction); - if(rc != 0) - throw System_Error("run_cpu_instruction_probe sigaction failed", errno); + if (rc != 0) throw System_Error("run_cpu_instruction_probe sigaction failed", errno); - rc = sigsetjmp(g_sigill_jmp_buf, /*save sigs*/1); + rc = sigsetjmp(g_sigill_jmp_buf, /*save sigs*/ 1); - if(rc == 0) - { - // first call to sigsetjmp - probe_result = probe_fn(); - } - else if(rc == 1) - { - // non-local return from siglongjmp in signal handler: return error - probe_result = -1; - } + if (rc == 0) { + // first call to sigsetjmp + probe_result = probe_fn(); + } else if (rc == 1) { + // non-local return from siglongjmp in signal handler: return error + probe_result = -1; + } - // Restore old SIGILL handler, if any - rc = ::sigaction(SIGILL, &old_sigaction, nullptr); - if(rc != 0) - throw System_Error("run_cpu_instruction_probe sigaction restore failed", errno); + // Restore old SIGILL handler, if any + rc = ::sigaction(SIGILL, &old_sigaction, nullptr); + if (rc != 0) throw System_Error("run_cpu_instruction_probe sigaction restore failed", errno); #elif defined(BOTAN_TARGET_OS_IS_WINDOWS) && defined(BOTAN_TARGET_COMPILER_IS_MSVC) - // Windows SEH - __try - { - probe_result = probe_fn(); - } - __except(::GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION ? - EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - probe_result = -1; - } + // Windows SEH + __try { + probe_result = probe_fn(); + } __except (::GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION ? EXCEPTION_EXECUTE_HANDLER + : EXCEPTION_CONTINUE_SEARCH) { + probe_result = -1; + } #else - BOTAN_UNUSED(probe_fn); + BOTAN_UNUSED(probe_fn); #endif - return probe_result; - } + return probe_result; +} -std::unique_ptr OS::suppress_echo_on_terminal() - { +std::unique_ptr OS::suppress_echo_on_terminal() { #if defined(BOTAN_TARGET_OS_HAS_POSIX1) - class POSIX_Echo_Suppression : public Echo_Suppression - { - public: - POSIX_Echo_Suppression() - { + class POSIX_Echo_Suppression : public Echo_Suppression { + public: + POSIX_Echo_Suppression() { m_stdin_fd = fileno(stdin); - if(::tcgetattr(m_stdin_fd, &m_old_termios) != 0) - throw System_Error("Getting terminal status failed", errno); + if (::tcgetattr(m_stdin_fd, &m_old_termios) != 0) + throw System_Error("Getting terminal status failed", errno); struct termios noecho_flags = m_old_termios; noecho_flags.c_lflag &= ~ECHO; noecho_flags.c_lflag |= ECHONL; - if(::tcsetattr(m_stdin_fd, TCSANOW, &noecho_flags) != 0) - throw System_Error("Clearing terminal echo bit failed", errno); + if (::tcsetattr(m_stdin_fd, TCSANOW, &noecho_flags) != 0) + throw System_Error("Clearing terminal echo bit failed", errno); + } + + void reenable_echo() override { + if (m_stdin_fd > 0) { + if (::tcsetattr(m_stdin_fd, TCSANOW, &m_old_termios) != 0) + throw System_Error("Restoring terminal echo bit failed", errno); + m_stdin_fd = -1; } + } - void reenable_echo() override - { - if(m_stdin_fd > 0) - { - if(::tcsetattr(m_stdin_fd, TCSANOW, &m_old_termios) != 0) - throw System_Error("Restoring terminal echo bit failed", errno); - m_stdin_fd = -1; - } + ~POSIX_Echo_Suppression() { + try { + reenable_echo(); + } catch (...) { } + } - ~POSIX_Echo_Suppression() - { - try - { - reenable_echo(); - } - catch(...) - { - } - } + private: + int m_stdin_fd; + struct termios m_old_termios; + }; - private: - int m_stdin_fd; - struct termios m_old_termios; - }; - - return std::unique_ptr(new POSIX_Echo_Suppression); + return std::unique_ptr(new POSIX_Echo_Suppression); #elif defined(BOTAN_TARGET_OS_HAS_WIN32) - class Win32_Echo_Suppression : public Echo_Suppression - { - public: - Win32_Echo_Suppression() - { + class Win32_Echo_Suppression : public Echo_Suppression { + public: + Win32_Echo_Suppression() { m_input_handle = ::GetStdHandle(STD_INPUT_HANDLE); - if(::GetConsoleMode(m_input_handle, &m_console_state) == 0) - throw System_Error("Getting console mode failed", ::GetLastError()); + if (::GetConsoleMode(m_input_handle, &m_console_state) == 0) + throw System_Error("Getting console mode failed", ::GetLastError()); DWORD new_mode = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; - if(::SetConsoleMode(m_input_handle, new_mode) == 0) - throw System_Error("Setting console mode failed", ::GetLastError()); + if (::SetConsoleMode(m_input_handle, new_mode) == 0) + throw System_Error("Setting console mode failed", ::GetLastError()); + } + + void reenable_echo() override { + if (m_input_handle != INVALID_HANDLE_VALUE) { + if (::SetConsoleMode(m_input_handle, m_console_state) == 0) + throw System_Error("Setting console mode failed", ::GetLastError()); + m_input_handle = INVALID_HANDLE_VALUE; } + } - void reenable_echo() override - { - if(m_input_handle != INVALID_HANDLE_VALUE) - { - if(::SetConsoleMode(m_input_handle, m_console_state) == 0) - throw System_Error("Setting console mode failed", ::GetLastError()); - m_input_handle = INVALID_HANDLE_VALUE; - } + ~Win32_Echo_Suppression() { + try { + reenable_echo(); + } catch (...) { } + } - ~Win32_Echo_Suppression() - { - try - { - reenable_echo(); - } - catch(...) - { - } - } + private: + HANDLE m_input_handle; + DWORD m_console_state; + }; - private: - HANDLE m_input_handle; - DWORD m_console_state; - }; - - return std::unique_ptr(new Win32_Echo_Suppression); + return std::unique_ptr(new Win32_Echo_Suppression); #else - // Not supported on this platform, return null - return std::unique_ptr(); + // Not supported on this platform, return null + return std::unique_ptr(); #endif - } - } + +} // namespace Botan /* -* Various string utils and parsing functions -* (C) 1999-2007,2013,2014,2015,2018 Jack Lloyd -* (C) 2015 Simon Warta (Kullo GmbH) -* (C) 2017 René Korthaus, Rohde & Schwarz Cybersecurity -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Various string utils and parsing functions + * (C) 1999-2007,2013,2014,2015,2018 Jack Lloyd + * (C) 2015 Simon Warta (Kullo GmbH) + * (C) 2017 René Korthaus, Rohde & Schwarz Cybersecurity + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #include @@ -25905,739 +23207,607 @@ std::unique_ptr OS::suppress_echo_on_terminal() namespace Botan { -uint16_t to_uint16(const std::string& str) - { - const uint32_t x = to_u32bit(str); +uint16_t to_uint16(const std::string& str) { + const uint32_t x = to_u32bit(str); - if(x >> 16) - throw Invalid_Argument("Integer value exceeds 16 bit range"); + if (x >> 16) throw Invalid_Argument("Integer value exceeds 16 bit range"); - return static_cast(x); - } + return static_cast(x); +} -uint32_t to_u32bit(const std::string& str) - { - // std::stoul is not strict enough. Ensure that str is digit only [0-9]* - for(const char chr : str) - { - if(chr < '0' || chr > '9') - { - std::string chrAsString(1, chr); - throw Invalid_Argument("String contains non-digit char: " + chrAsString); - } - } +uint32_t to_u32bit(const std::string& str) { + // std::stoul is not strict enough. Ensure that str is digit only [0-9]* + for (const char chr : str) { + if (chr < '0' || chr > '9') { + std::string chrAsString(1, chr); + throw Invalid_Argument("String contains non-digit char: " + chrAsString); + } + } - const unsigned long int x = std::stoul(str); + const unsigned long int x = std::stoul(str); - if(sizeof(unsigned long int) > 4) - { - // x might be uint64 - if (x > std::numeric_limits::max()) - { - throw Invalid_Argument("Integer value of " + str + " exceeds 32 bit range"); - } - } + if (sizeof(unsigned long int) > 4) { + // x might be uint64 + if (x > std::numeric_limits::max()) { + throw Invalid_Argument("Integer value of " + str + " exceeds 32 bit range"); + } + } - return static_cast(x); - } + return static_cast(x); +} /* -* Convert a string into a time duration -*/ -uint32_t timespec_to_u32bit(const std::string& timespec) - { - if(timespec.empty()) - return 0; + * Convert a string into a time duration + */ +uint32_t timespec_to_u32bit(const std::string& timespec) { + if (timespec.empty()) return 0; - const char suffix = timespec[timespec.size()-1]; - std::string value = timespec.substr(0, timespec.size()-1); + const char suffix = timespec[timespec.size() - 1]; + std::string value = timespec.substr(0, timespec.size() - 1); - uint32_t scale = 1; + uint32_t scale = 1; - if(Charset::is_digit(suffix)) - value += suffix; - else if(suffix == 's') - scale = 1; - else if(suffix == 'm') - scale = 60; - else if(suffix == 'h') - scale = 60 * 60; - else if(suffix == 'd') - scale = 24 * 60 * 60; - else if(suffix == 'y') - scale = 365 * 24 * 60 * 60; - else - throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec); + if (Charset::is_digit(suffix)) + value += suffix; + else if (suffix == 's') + scale = 1; + else if (suffix == 'm') + scale = 60; + else if (suffix == 'h') + scale = 60 * 60; + else if (suffix == 'd') + scale = 24 * 60 * 60; + else if (suffix == 'y') + scale = 365 * 24 * 60 * 60; + else + throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec); - return scale * to_u32bit(value); - } + return scale * to_u32bit(value); +} /* -* Parse a SCAN-style algorithm name -*/ -std::vector parse_algorithm_name(const std::string& namex) - { - if(namex.find('(') == std::string::npos && - namex.find(')') == std::string::npos) - return std::vector(1, namex); + * Parse a SCAN-style algorithm name + */ +std::vector parse_algorithm_name(const std::string& namex) { + if (namex.find('(') == std::string::npos && namex.find(')') == std::string::npos) + return std::vector(1, namex); - std::string name = namex, substring; - std::vector elems; - size_t level = 0; + std::string name = namex, substring; + std::vector elems; + size_t level = 0; - elems.push_back(name.substr(0, name.find('('))); - name = name.substr(name.find('(')); + elems.push_back(name.substr(0, name.find('('))); + name = name.substr(name.find('(')); - for(auto i = name.begin(); i != name.end(); ++i) - { - char c = *i; + for (auto i = name.begin(); i != name.end(); ++i) { + char c = *i; - if(c == '(') - ++level; - if(c == ')') - { - if(level == 1 && i == name.end() - 1) - { - if(elems.size() == 1) - elems.push_back(substring.substr(1)); - else - elems.push_back(substring); - return elems; + if (c == '(') ++level; + if (c == ')') { + if (level == 1 && i == name.end() - 1) { + if (elems.size() == 1) + elems.push_back(substring.substr(1)); + else + elems.push_back(substring); + return elems; } - if(level == 0 || (level == 1 && i != name.end() - 1)) - throw Invalid_Algorithm_Name(namex); - --level; - } + if (level == 0 || (level == 1 && i != name.end() - 1)) + throw Invalid_Algorithm_Name(namex); + --level; + } - if(c == ',' && level == 1) - { - if(elems.size() == 1) - elems.push_back(substring.substr(1)); - else - elems.push_back(substring); - substring.clear(); - } - else - substring += c; - } + if (c == ',' && level == 1) { + if (elems.size() == 1) + elems.push_back(substring.substr(1)); + else + elems.push_back(substring); + substring.clear(); + } else + substring += c; + } - if(!substring.empty()) - throw Invalid_Algorithm_Name(namex); + if (!substring.empty()) throw Invalid_Algorithm_Name(namex); - return elems; - } + return elems; +} -std::vector split_on(const std::string& str, char delim) - { - return split_on_pred(str, [delim](char c) { return c == delim; }); - } +std::vector split_on(const std::string& str, char delim) { + return split_on_pred(str, [delim](char c) { return c == delim; }); +} -std::vector split_on_pred(const std::string& str, - std::function pred) - { - std::vector elems; - if(str.empty()) return elems; +std::vector split_on_pred(const std::string& str, std::function pred) { + std::vector elems; + if (str.empty()) return elems; - std::string substr; - for(auto i = str.begin(); i != str.end(); ++i) - { - if(pred(*i)) - { - if(!substr.empty()) - elems.push_back(substr); - substr.clear(); - } - else - substr += *i; - } + std::string substr; + for (auto i = str.begin(); i != str.end(); ++i) { + if (pred(*i)) { + if (!substr.empty()) elems.push_back(substr); + substr.clear(); + } else + substr += *i; + } - if(substr.empty()) - throw Invalid_Argument("Unable to split string: " + str); - elems.push_back(substr); + if (substr.empty()) throw Invalid_Argument("Unable to split string: " + str); + elems.push_back(substr); - return elems; - } + return elems; +} /* -* Join a string -*/ -std::string string_join(const std::vector& strs, char delim) - { - std::string out = ""; + * Join a string + */ +std::string string_join(const std::vector& strs, char delim) { + std::string out = ""; - for(size_t i = 0; i != strs.size(); ++i) - { - if(i != 0) - out += delim; - out += strs[i]; - } + for (size_t i = 0; i != strs.size(); ++i) { + if (i != 0) out += delim; + out += strs[i]; + } - return out; - } + return out; +} /* -* Parse an ASN.1 OID string -*/ -std::vector parse_asn1_oid(const std::string& oid) - { + * Parse an ASN.1 OID string + */ +std::vector parse_asn1_oid(const std::string& oid) { #if defined(BOTAN_HAS_ASN1) - return OID(oid).get_components(); + return OID(oid).get_components(); #else - throw Not_Implemented("ASN1 support not available"); + throw Not_Implemented("ASN1 support not available"); #endif - } +} /* -* X.500 String Comparison -*/ -bool x500_name_cmp(const std::string& name1, const std::string& name2) - { - auto p1 = name1.begin(); - auto p2 = name2.begin(); + * X.500 String Comparison + */ +bool x500_name_cmp(const std::string& name1, const std::string& name2) { + auto p1 = name1.begin(); + auto p2 = name2.begin(); - while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; - while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; + while ((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; + while ((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; - while(p1 != name1.end() && p2 != name2.end()) - { - if(Charset::is_space(*p1)) - { - if(!Charset::is_space(*p2)) - return false; + while (p1 != name1.end() && p2 != name2.end()) { + if (Charset::is_space(*p1)) { + if (!Charset::is_space(*p2)) return false; - while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; - while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; + while ((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; + while ((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; - if(p1 == name1.end() && p2 == name2.end()) - return true; - if(p1 == name1.end() || p2 == name2.end()) - return false; - } + if (p1 == name1.end() && p2 == name2.end()) return true; + if (p1 == name1.end() || p2 == name2.end()) return false; + } - if(!Charset::caseless_cmp(*p1, *p2)) - return false; - ++p1; - ++p2; - } + if (!Charset::caseless_cmp(*p1, *p2)) return false; + ++p1; + ++p2; + } - while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; - while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; + while ((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; + while ((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; - if((p1 != name1.end()) || (p2 != name2.end())) - return false; - return true; - } + if ((p1 != name1.end()) || (p2 != name2.end())) return false; + return true; +} /* -* Convert a decimal-dotted string to binary IP -*/ -uint32_t string_to_ipv4(const std::string& str) - { - std::vector parts = split_on(str, '.'); + * Convert a decimal-dotted string to binary IP + */ +uint32_t string_to_ipv4(const std::string& str) { + std::vector parts = split_on(str, '.'); - if(parts.size() != 4) - throw Decoding_Error("Invalid IP string " + str); + if (parts.size() != 4) throw Decoding_Error("Invalid IP string " + str); - uint32_t ip = 0; + uint32_t ip = 0; - for(auto part = parts.begin(); part != parts.end(); ++part) - { - uint32_t octet = to_u32bit(*part); + for (auto part = parts.begin(); part != parts.end(); ++part) { + uint32_t octet = to_u32bit(*part); - if(octet > 255) - throw Decoding_Error("Invalid IP string " + str); + if (octet > 255) throw Decoding_Error("Invalid IP string " + str); - ip = (ip << 8) | (octet & 0xFF); - } + ip = (ip << 8) | (octet & 0xFF); + } - return ip; - } + return ip; +} /* -* Convert an IP address to decimal-dotted string -*/ -std::string ipv4_to_string(uint32_t ip) - { - std::string str; + * Convert an IP address to decimal-dotted string + */ +std::string ipv4_to_string(uint32_t ip) { + std::string str; - for(size_t i = 0; i != sizeof(ip); ++i) - { - if(i) - str += "."; - str += std::to_string(get_byte(i, ip)); - } + for (size_t i = 0; i != sizeof(ip); ++i) { + if (i) str += "."; + str += std::to_string(get_byte(i, ip)); + } - return str; - } + return str; +} -std::string erase_chars(const std::string& str, const std::set& chars) - { - std::string out; +std::string erase_chars(const std::string& str, const std::set& chars) { + std::string out; - for(auto c: str) - if(chars.count(c) == 0) - out += c; + for (auto c : str) + if (chars.count(c) == 0) out += c; - return out; - } + return out; +} -std::string replace_chars(const std::string& str, - const std::set& chars, - char to_char) - { - std::string out = str; +std::string replace_chars(const std::string& str, const std::set& chars, char to_char) { + std::string out = str; - for(size_t i = 0; i != out.size(); ++i) - if(chars.count(out[i])) - out[i] = to_char; + for (size_t i = 0; i != out.size(); ++i) + if (chars.count(out[i])) out[i] = to_char; - return out; - } + return out; +} -std::string replace_char(const std::string& str, char from_char, char to_char) - { - std::string out = str; +std::string replace_char(const std::string& str, char from_char, char to_char) { + std::string out = str; - for(size_t i = 0; i != out.size(); ++i) - if(out[i] == from_char) - out[i] = to_char; + for (size_t i = 0; i != out.size(); ++i) + if (out[i] == from_char) out[i] = to_char; - return out; - } + return out; +} namespace { -std::string tolower_string(const std::string& in) - { - std::string s = in; - for(size_t i = 0; i != s.size(); ++i) - { - const int cu = static_cast(s[i]); - if(std::isalpha(cu)) - s[i] = static_cast(std::tolower(cu)); - } - return s; - } - +std::string tolower_string(const std::string& in) { + std::string s = in; + for (size_t i = 0; i != s.size(); ++i) { + const int cu = static_cast(s[i]); + if (std::isalpha(cu)) s[i] = static_cast(std::tolower(cu)); + } + return s; } -bool host_wildcard_match(const std::string& issued_, const std::string& host_) - { - const std::string issued = tolower_string(issued_); - const std::string host = tolower_string(host_); +} // namespace - if(host.empty() || issued.empty()) - return false; +bool host_wildcard_match(const std::string& issued_, const std::string& host_) { + const std::string issued = tolower_string(issued_); + const std::string host = tolower_string(host_); - /* - If there are embedded nulls in your issued name - Well I feel bad for you son - */ - if(std::count(issued.begin(), issued.end(), char(0)) > 0) - return false; + if (host.empty() || issued.empty()) return false; - // If more than one wildcard, then issued name is invalid - const size_t stars = std::count(issued.begin(), issued.end(), '*'); - if(stars > 1) - return false; + /* + If there are embedded nulls in your issued name + Well I feel bad for you son + */ + if (std::count(issued.begin(), issued.end(), char(0)) > 0) return false; - // '*' is not a valid character in DNS names so should not appear on the host side - if(std::count(host.begin(), host.end(), '*') != 0) - return false; + // If more than one wildcard, then issued name is invalid + const size_t stars = std::count(issued.begin(), issued.end(), '*'); + if (stars > 1) return false; - // Similarly a DNS name can't end in . - if(host[host.size() - 1] == '.') - return false; + // '*' is not a valid character in DNS names so should not appear on the host side + if (std::count(host.begin(), host.end(), '*') != 0) return false; - // And a host can't have an empty name component, so reject that - if(host.find("..") != std::string::npos) - return false; + // Similarly a DNS name can't end in . + if (host[host.size() - 1] == '.') return false; - // Exact match: accept - if(issued == host) - { - return true; - } + // And a host can't have an empty name component, so reject that + if (host.find("..") != std::string::npos) return false; - /* - Otherwise it might be a wildcard + // Exact match: accept + if (issued == host) { + return true; + } - If the issued size is strictly longer than the hostname size it - couldn't possibly be a match, even if the issued value is a - wildcard. The only exception is when the wildcard ends up empty - (eg www.example.com matches www*.example.com) - */ - if(issued.size() > host.size() + 1) - { - return false; - } + /* + Otherwise it might be a wildcard - // If no * at all then not a wildcard, and so not a match - if(stars != 1) - { - return false; - } + If the issued size is strictly longer than the hostname size it + couldn't possibly be a match, even if the issued value is a + wildcard. The only exception is when the wildcard ends up empty + (eg www.example.com matches www*.example.com) + */ + if (issued.size() > host.size() + 1) { + return false; + } - /* - Now walk through the issued string, making sure every character - matches. When we come to the (singular) '*', jump forward in the - hostname by the corresponding amount. We know exactly how much - space the wildcard takes because it must be exactly `len(host) - - len(issued) + 1 chars`. + // If no * at all then not a wildcard, and so not a match + if (stars != 1) { + return false; + } - We also verify that the '*' comes in the leftmost component, and - doesn't skip over any '.' in the hostname. - */ - size_t dots_seen = 0; - size_t host_idx = 0; + /* + Now walk through the issued string, making sure every character + matches. When we come to the (singular) '*', jump forward in the + hostname by the corresponding amount. We know exactly how much + space the wildcard takes because it must be exactly `len(host) - + len(issued) + 1 chars`. - for(size_t i = 0; i != issued.size(); ++i) - { - dots_seen += (issued[i] == '.'); + We also verify that the '*' comes in the leftmost component, and + doesn't skip over any '.' in the hostname. + */ + size_t dots_seen = 0; + size_t host_idx = 0; - if(issued[i] == '*') - { - // Fail: wildcard can only come in leftmost component - if(dots_seen > 0) - { - return false; + for (size_t i = 0; i != issued.size(); ++i) { + dots_seen += (issued[i] == '.'); + + if (issued[i] == '*') { + // Fail: wildcard can only come in leftmost component + if (dots_seen > 0) { + return false; } - /* - Since there is only one * we know the tail of the issued and - hostname must be an exact match. In this case advance host_idx - to match. - */ - const size_t advance = (host.size() - issued.size() + 1); + /* + Since there is only one * we know the tail of the issued and + hostname must be an exact match. In this case advance host_idx + to match. + */ + const size_t advance = (host.size() - issued.size() + 1); - if(host_idx + advance > host.size()) // shouldn't happen - return false; + if (host_idx + advance > host.size()) // shouldn't happen + return false; - // Can't be any intervening .s that we would have skipped - if(std::count(host.begin() + host_idx, - host.begin() + host_idx + advance, '.') != 0) - return false; + // Can't be any intervening .s that we would have skipped + if (std::count(host.begin() + host_idx, host.begin() + host_idx + advance, '.') != 0) + return false; - host_idx += advance; - } - else - { - if(issued[i] != host[host_idx]) - { - return false; + host_idx += advance; + } else { + if (issued[i] != host[host_idx]) { + return false; } - host_idx += 1; - } - } + host_idx += 1; + } + } - // Wildcard issued name must have at least 3 components - if(dots_seen < 2) - { - return false; - } - - return true; - } + // Wildcard issued name must have at least 3 components + if (dots_seen < 2) { + return false; + } + return true; } + +} // namespace Botan /* -* Simple config/test file reader -* (C) 2013,2014,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - + * Simple config/test file reader + * (C) 2013,2014,2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -std::string clean_ws(const std::string& s) - { - const char* ws = " \t\n"; - auto start = s.find_first_not_of(ws); - auto end = s.find_last_not_of(ws); +std::string clean_ws(const std::string& s) { + const char* ws = " \t\n"; + auto start = s.find_first_not_of(ws); + auto end = s.find_last_not_of(ws); - if(start == std::string::npos) - return ""; - - if(end == std::string::npos) - return s.substr(start, end); - else - return s.substr(start, start + end + 1); - } - -std::map read_cfg(std::istream& is) - { - std::map kv; - size_t line = 0; - - while(is.good()) - { - std::string s; - - std::getline(is, s); - - ++line; - - if(s.empty() || s[0] == '#') - continue; - - s = clean_ws(s.substr(0, s.find('#'))); - - if(s.empty()) - continue; - - auto eq = s.find("="); - - if(eq == std::string::npos || eq == 0 || eq == s.size() - 1) - throw Decoding_Error("Bad read_cfg input '" + s + "' on line " + std::to_string(line)); - - const std::string key = clean_ws(s.substr(0, eq)); - const std::string val = clean_ws(s.substr(eq + 1, std::string::npos)); - - kv[key] = val; - } - - return kv; - } + if (start == std::string::npos) return ""; + if (end == std::string::npos) + return s.substr(start, end); + else + return s.substr(start, start + end + 1); } -/* -* (C) 2018 Ribose Inc -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +std::map read_cfg(std::istream& is) { + std::map kv; + size_t line = 0; + + while (is.good()) { + std::string s; + + std::getline(is, s); + + ++line; + + if (s.empty() || s[0] == '#') continue; + + s = clean_ws(s.substr(0, s.find('#'))); + + if (s.empty()) continue; + + auto eq = s.find("="); + + if (eq == std::string::npos || eq == 0 || eq == s.size() - 1) + throw Decoding_Error("Bad read_cfg input '" + s + "' on line " + std::to_string(line)); + + const std::string key = clean_ws(s.substr(0, eq)); + const std::string val = clean_ws(s.substr(eq + 1, std::string::npos)); + + kv[key] = val; + } + + return kv; +} + +} // namespace Botan +/* + * (C) 2018 Ribose Inc + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -std::map read_kv(const std::string& kv) - { - std::map m; - if(kv == "") - return m; +std::map read_kv(const std::string& kv) { + std::map m; + if (kv == "") return m; - std::vector parts; + std::vector parts; - try - { - parts = split_on(kv, ','); - } - catch(std::exception&) - { - throw Invalid_Argument("Bad KV spec"); - } + try { + parts = split_on(kv, ','); + } catch (std::exception&) { + throw Invalid_Argument("Bad KV spec"); + } - bool escaped = false; - bool reading_key = true; - std::string cur_key; - std::string cur_val; + bool escaped = false; + bool reading_key = true; + std::string cur_key; + std::string cur_val; - for(char c : kv) - { - if(c == '\\' && !escaped) - { - escaped = true; - } - else if(c == ',' && !escaped) - { - if(cur_key.empty()) - throw Invalid_Argument("Bad KV spec empty key"); + for (char c : kv) { + if (c == '\\' && !escaped) { + escaped = true; + } else if (c == ',' && !escaped) { + if (cur_key.empty()) throw Invalid_Argument("Bad KV spec empty key"); - if(m.find(cur_key) != m.end()) - throw Invalid_Argument("Bad KV spec duplicated key"); - m[cur_key] = cur_val; - cur_key = ""; - cur_val = ""; - reading_key = true; - } - else if(c == '=' && !escaped) - { - if(reading_key == false) - throw Invalid_Argument("Bad KV spec unexpected equals sign"); - reading_key = false; - } - else - { - if(reading_key) - cur_key += c; - else - cur_val += c; + if (m.find(cur_key) != m.end()) throw Invalid_Argument("Bad KV spec duplicated key"); + m[cur_key] = cur_val; + cur_key = ""; + cur_val = ""; + reading_key = true; + } else if (c == '=' && !escaped) { + if (reading_key == false) throw Invalid_Argument("Bad KV spec unexpected equals sign"); + reading_key = false; + } else { + if (reading_key) + cur_key += c; + else + cur_val += c; - if(escaped) - escaped = false; - } - } + if (escaped) escaped = false; + } + } - if(!cur_key.empty()) - { - if(reading_key == false) - { - if(m.find(cur_key) != m.end()) - throw Invalid_Argument("Bad KV spec duplicated key"); - m[cur_key] = cur_val; - } - else - throw Invalid_Argument("Bad KV spec incomplete string"); - } - - return m; - } + if (!cur_key.empty()) { + if (reading_key == false) { + if (m.find(cur_key) != m.end()) throw Invalid_Argument("Bad KV spec duplicated key"); + m[cur_key] = cur_val; + } else + throw Invalid_Argument("Bad KV spec incomplete string"); + } + return m; } -/* -* (C) 2018 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +} // namespace Botan +/* + * (C) 2018 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { -void Timer::start() - { - stop(); - m_timer_start = OS::get_system_timestamp_ns(); - m_cpu_cycles_start = OS::get_cpu_cycle_counter(); - } - -void Timer::stop() - { - if(m_timer_start) - { - if(m_cpu_cycles_start != 0) - { - const uint64_t cycles_taken = OS::get_cpu_cycle_counter() - m_cpu_cycles_start; - if(cycles_taken > 0) - { - m_cpu_cycles_used += static_cast(cycles_taken * m_clock_cycle_ratio); - } - } - - const uint64_t now = OS::get_system_timestamp_ns(); - - if(now > m_timer_start) - { - const uint64_t dur = now - m_timer_start; - - m_time_used += dur; - - if(m_event_count == 0) - { - m_min_time = m_max_time = dur; - } - else - { - m_max_time = std::max(m_max_time, dur); - m_min_time = std::min(m_min_time, dur); - } - } - - m_timer_start = 0; - ++m_event_count; - } - } - -bool Timer::operator<(const Timer& other) const - { - if(this->doing() != other.doing()) - return (this->doing() < other.doing()); - - return (this->get_name() < other.get_name()); - } - -std::string Timer::to_string() const - { - if(m_custom_msg.size() > 0) - { - return m_custom_msg; - } - else if(this->buf_size() == 0) - { - return result_string_ops(); - } - else - { - return result_string_bps(); - } - } - -std::string Timer::result_string_bps() const - { - const size_t MiB = 1024 * 1024; - - const double MiB_total = static_cast(events()) / MiB; - const double MiB_per_sec = MiB_total / seconds(); - - std::ostringstream oss; - oss << get_name(); - - if(!doing().empty()) - { - oss << " " << doing(); - } - - if(buf_size() > 0) - { - oss << " buffer size " << buf_size() << " bytes:"; - } - - if(events() == 0) - oss << " " << "N/A"; - else - oss << " " << std::fixed << std::setprecision(3) << MiB_per_sec << " MiB/sec"; - - if(cycles_consumed() != 0) - { - const double cycles_per_byte = static_cast(cycles_consumed()) / events(); - oss << " " << std::fixed << std::setprecision(2) << cycles_per_byte << " cycles/byte"; - } - - oss << " (" << MiB_total << " MiB in " << milliseconds() << " ms)\n"; - - return oss.str(); - } - -std::string Timer::result_string_ops() const - { - std::ostringstream oss; - - oss << get_name() << " "; - - if(events() == 0) - { - oss << "no events\n"; - } - else - { - oss << static_cast(events_per_second()) - << ' ' << doing() << "/sec; " - << std::setprecision(2) << std::fixed - << ms_per_event() << " ms/op"; - - if(cycles_consumed() != 0) - { - const double cycles_per_op = static_cast(cycles_consumed()) / events(); - const size_t precision = (cycles_per_op < 10000) ? 2 : 0; - oss << " " << std::fixed << std::setprecision(precision) << cycles_per_op << " cycles/op"; - } - - oss << " (" << events() << " " << (events() == 1 ? "op" : "ops") - << " in " << milliseconds() << " ms)\n"; - } - - return oss.str(); - } - +void Timer::start() { + stop(); + m_timer_start = OS::get_system_timestamp_ns(); + m_cpu_cycles_start = OS::get_cpu_cycle_counter(); } -/* -* Version Information -* (C) 1999-2013,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ +void Timer::stop() { + if (m_timer_start) { + if (m_cpu_cycles_start != 0) { + const uint64_t cycles_taken = OS::get_cpu_cycle_counter() - m_cpu_cycles_start; + if (cycles_taken > 0) { + m_cpu_cycles_used += static_cast(cycles_taken * m_clock_cycle_ratio); + } + } + + const uint64_t now = OS::get_system_timestamp_ns(); + + if (now > m_timer_start) { + const uint64_t dur = now - m_timer_start; + + m_time_used += dur; + + if (m_event_count == 0) { + m_min_time = m_max_time = dur; + } else { + m_max_time = std::max(m_max_time, dur); + m_min_time = std::min(m_min_time, dur); + } + } + + m_timer_start = 0; + ++m_event_count; + } +} + +bool Timer::operator<(const Timer& other) const { + if (this->doing() != other.doing()) return (this->doing() < other.doing()); + + return (this->get_name() < other.get_name()); +} + +std::string Timer::to_string() const { + if (m_custom_msg.size() > 0) { + return m_custom_msg; + } else if (this->buf_size() == 0) { + return result_string_ops(); + } else { + return result_string_bps(); + } +} + +std::string Timer::result_string_bps() const { + const size_t MiB = 1024 * 1024; + + const double MiB_total = static_cast(events()) / MiB; + const double MiB_per_sec = MiB_total / seconds(); + + std::ostringstream oss; + oss << get_name(); + + if (!doing().empty()) { + oss << " " << doing(); + } + + if (buf_size() > 0) { + oss << " buffer size " << buf_size() << " bytes:"; + } + + if (events() == 0) + oss << " " << "N/A"; + else + oss << " " << std::fixed << std::setprecision(3) << MiB_per_sec << " MiB/sec"; + + if (cycles_consumed() != 0) { + const double cycles_per_byte = static_cast(cycles_consumed()) / events(); + oss << " " << std::fixed << std::setprecision(2) << cycles_per_byte << " cycles/byte"; + } + + oss << " (" << MiB_total << " MiB in " << milliseconds() << " ms)\n"; + + return oss.str(); +} + +std::string Timer::result_string_ops() const { + std::ostringstream oss; + + oss << get_name() << " "; + + if (events() == 0) { + oss << "no events\n"; + } else { + oss << static_cast(events_per_second()) << ' ' << doing() << "/sec; " + << std::setprecision(2) << std::fixed << ms_per_event() << " ms/op"; + + if (cycles_consumed() != 0) { + const double cycles_per_op = static_cast(cycles_consumed()) / events(); + const size_t precision = (cycles_per_op < 10000) ? 2 : 0; + oss << " " << std::fixed << std::setprecision(precision) << cycles_per_op + << " cycles/op"; + } + + oss << " (" << events() << " " << (events() == 1 ? "op" : "ops") << " in " << milliseconds() + << " ms)\n"; + } + + return oss.str(); +} + +} // namespace Botan +/* + * Version Information + * (C) 1999-2013,2015 Jack Lloyd + * + * Botan is released under the Simplified BSD License (see license.txt) + */ namespace Botan { @@ -26650,22 +23820,17 @@ namespace Botan { #define QUOTE(name) #name #define STR(macro) QUOTE(macro) -const char* short_version_cstr() - { - return STR(BOTAN_VERSION_MAJOR) "." - STR(BOTAN_VERSION_MINOR) "." - STR(BOTAN_VERSION_PATCH); - } +const char* short_version_cstr() { + return STR(BOTAN_VERSION_MAJOR) "." STR(BOTAN_VERSION_MINOR) "." STR(BOTAN_VERSION_PATCH); +} -const char* version_cstr() - { +const char* version_cstr() { + /* + It is intentional that this string is a compile-time constant; + it makes it much easier to find in binaries. + */ - /* - It is intentional that this string is a compile-time constant; - it makes it much easier to find in binaries. - */ - - return "Botan " STR(BOTAN_VERSION_MAJOR) "." + return "Botan " STR(BOTAN_VERSION_MAJOR) "." STR(BOTAN_VERSION_MINOR) "." STR(BOTAN_VERSION_PATCH) " (" #if defined(BOTAN_UNSAFE_FUZZER_MODE) @@ -26677,47 +23842,37 @@ const char* version_cstr() #endif ", revision " BOTAN_VERSION_VC_REVISION ", distribution " BOTAN_DISTRIBUTION_INFO ")"; - } +} #undef STR #undef QUOTE /* -* Return the version as a string -*/ -std::string version_string() - { - return std::string(version_cstr()); - } + * Return the version as a string + */ +std::string version_string() { return std::string(version_cstr()); } -std::string short_version_string() - { - return std::string(short_version_cstr()); - } +std::string short_version_string() { return std::string(short_version_cstr()); } uint32_t version_datestamp() { return BOTAN_VERSION_DATESTAMP; } /* -* Return parts of the version as integers -*/ + * Return parts of the version as integers + */ uint32_t version_major() { return BOTAN_VERSION_MAJOR; } uint32_t version_minor() { return BOTAN_VERSION_MINOR; } uint32_t version_patch() { return BOTAN_VERSION_PATCH; } -std::string runtime_version_check(uint32_t major, - uint32_t minor, - uint32_t patch) - { - if(major != version_major() || minor != version_minor() || patch != version_patch()) - { - std::ostringstream oss; - oss << "Warning: linked version (" << short_version_string() << ")" - << " does not match version built against " - << "(" << major << '.' << minor << '.' << patch << ")\n"; - return oss.str(); - } - - return ""; - } +std::string runtime_version_check(uint32_t major, uint32_t minor, uint32_t patch) { + if (major != version_major() || minor != version_minor() || patch != version_patch()) { + std::ostringstream oss; + oss << "Warning: linked version (" << short_version_string() << ")" + << " does not match version built against " + << "(" << major << '.' << minor << '.' << patch << ")\n"; + return oss.str(); + } + return ""; } + +} // namespace Botan diff --git a/src/libraries/botan/botan.h b/src/libraries/botan/botan.h index b4d737833..0cb2441ad 100644 --- a/src/libraries/botan/botan.h +++ b/src/libraries/botan/botan.h @@ -1,9 +1,9 @@ /* -* Botan 2.12.0 Amalgamation -* (C) 1999-2018 The Botan Authors -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Botan 2.12.0 Amalgamation + * (C) 1999-2018 The Botan Authors + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #ifndef BOTAN_AMALGAMATION_H_ #define BOTAN_AMALGAMATION_H_ @@ -30,14 +30,19 @@ #include /* -* This file was automatically generated running -* 'configure.py --cc=gcc --cc-bin=g++ --cpu=x86_64 --amalgamation --minimized-build --disable-shared --enable-modules=aes,base,base64,block,cbc,cbc_mac,checksum,cmac,codec_filt,filters,hash,hash_id,hex,hmac,hmac_drbg,kdf,kdf2,pbkdf,pbkdf2,sha1 --without-documentation --disable-sse2 --disable-ssse3 --disable-sse4.1 --disable-sse4.2 --disable-aes-ni --disable-sha-ni --cxxflags=-pipe -Wno-unused-parameter -fPIC' -* -* Target -* - Compiler: g++ -fstack-protector -m64 -pthread -std=c++11 -D_REENTRANT -pipe -Wno-unused-parameter -fPIC -* - Arch: x86_64 -* - OS: linux -*/ + * This file was automatically generated running + * 'configure.py --cc=gcc --cc-bin=g++ --cpu=x86_64 --amalgamation --minimized-build + * --disable-shared + * --enable-modules=aes,base,base64,block,cbc,cbc_mac,checksum,cmac,codec_filt,filters,hash,hash_id,hex,hmac,hmac_drbg,kdf,kdf2,pbkdf,pbkdf2,sha1 + * --without-documentation --disable-sse2 --disable-ssse3 --disable-sse4.1 --disable-sse4.2 + * --disable-aes-ni --disable-sha-ni --cxxflags=-pipe -Wno-unused-parameter -fPIC' + * + * Target + * - Compiler: g++ -fstack-protector -m64 -pthread -std=c++11 -D_REENTRANT -pipe + * -Wno-unused-parameter -fPIC + * - Arch: x86_64 + * - OS: linux + */ #define BOTAN_VERSION_MAJOR 2 #define BOTAN_VERSION_MINOR 12 @@ -53,7 +58,6 @@ /* How many bits per limb in a BigInt */ #define BOTAN_MP_WORD_BITS 64 - #define BOTAN_INSTALL_PREFIX R"(/usr/local)" #define BOTAN_INSTALL_HEADER_DIR "include/botan-2" #define BOTAN_INSTALL_LIB_DIR "/usr/local/lib" @@ -63,34 +67,30 @@ #define BOTAN_SYSTEM_CERT_BUNDLE "/etc/ssl/certs/ca-certificates.crt" #ifndef BOTAN_DLL - #define BOTAN_DLL +#define BOTAN_DLL #endif /* Target identification and feature test macros */ -//#define BOTAN_TARGET_OS_IS_LINUX +// #define BOTAN_TARGET_OS_IS_LINUX -//#define BOTAN_TARGET_OS_HAS_CLOCK_GETTIME +// #define BOTAN_TARGET_OS_HAS_CLOCK_GETTIME #define BOTAN_TARGET_OS_HAS_DEV_RANDOM #define BOTAN_TARGET_OS_HAS_FILESYSTEM -//#define BOTAN_TARGET_OS_HAS_GETAUXVAL -//#define BOTAN_TARGET_OS_HAS_POSIX1 -//#define BOTAN_TARGET_OS_HAS_POSIX_MLOCK +// #define BOTAN_TARGET_OS_HAS_GETAUXVAL +// #define BOTAN_TARGET_OS_HAS_POSIX1 +// #define BOTAN_TARGET_OS_HAS_POSIX_MLOCK #define BOTAN_TARGET_OS_HAS_PROC_FS #define BOTAN_TARGET_OS_HAS_SOCKETS #define BOTAN_TARGET_OS_HAS_THREAD_LOCAL #define BOTAN_TARGET_OS_HAS_THREADS +// #define BOTAN_BUILD_COMPILER_IS_GCC -//#define BOTAN_BUILD_COMPILER_IS_GCC - - - - -//#define BOTAN_TARGET_ARCH_IS_X86_64 +// #define BOTAN_TARGET_ARCH_IS_X86_64 #define BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN -//#define BOTAN_TARGET_CPU_IS_X86_FAMILY -//#define BOTAN_TARGET_CPU_HAS_NATIVE_64BIT +// #define BOTAN_TARGET_CPU_IS_X86_FAMILY +// #define BOTAN_TARGET_CPU_HAS_NATIVE_64BIT #define BOTAN_TARGET_SUPPORTS_AVX2 #define BOTAN_TARGET_SUPPORTS_BMI2 @@ -98,14 +98,9 @@ #define BOTAN_TARGET_SUPPORTS_RDSEED #define BOTAN_TARGET_SUPPORTS_SHA - - - - - /* -* Module availability definitions -*/ + * Module availability definitions + */ #define BOTAN_HAS_AES 20131128 #define BOTAN_HAS_ASN1 20171109 #define BOTAN_HAS_BASE64_CODEC 20131128 @@ -142,23 +137,21 @@ #define BOTAN_HAS_STATEFUL_RNG 20160819 #define BOTAN_HAS_UTIL_FUNCTIONS 20180903 +/* + * Local/misc configuration options (if any) follow + */ /* -* Local/misc configuration options (if any) follow -*/ - - -/* -* Things you can edit (but probably shouldn't) -*/ + * Things you can edit (but probably shouldn't) + */ #if !defined(BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES) - #if defined(BOTAN_NO_DEPRECATED) - #define BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES private - #else - #define BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES public - #endif +#if defined(BOTAN_NO_DEPRECATED) +#define BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES private +#else +#define BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES public +#endif #endif @@ -166,48 +159,48 @@ #define BOTAN_DEFAULT_BUFFER_SIZE 1024 /* -* Total maximum amount of RAM (in KiB) we will lock into memory, even -* if the OS would let us lock more -*/ + * Total maximum amount of RAM (in KiB) we will lock into memory, even + * if the OS would let us lock more + */ #define BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB 512 /* -* If BOTAN_MEM_POOL_USE_MMU_PROTECTIONS is defined, the Memory_Pool -* class used for mlock'ed memory will use OS calls to set page -* permissions so as to prohibit access to pages on the free list, then -* enable read/write access when the page is set to be used. This will -* turn (some) use after free bugs into a crash. -* -* The additional syscalls have a substantial performance impact, which -* is why this option is not enabled by default. -*/ + * If BOTAN_MEM_POOL_USE_MMU_PROTECTIONS is defined, the Memory_Pool + * class used for mlock'ed memory will use OS calls to set page + * permissions so as to prohibit access to pages on the free list, then + * enable read/write access when the page is set to be used. This will + * turn (some) use after free bugs into a crash. + * + * The additional syscalls have a substantial performance impact, which + * is why this option is not enabled by default. + */ #if defined(BOTAN_HAS_VALGRIND) || defined(BOTAN_ENABLE_DEBUG_ASSERTS) - #define BOTAN_MEM_POOL_USE_MMU_PROTECTIONS +#define BOTAN_MEM_POOL_USE_MMU_PROTECTIONS #endif /* -* If enabled uses memset via volatile function pointer to zero memory, -* otherwise does a byte at a time write via a volatile pointer. -*/ + * If enabled uses memset via volatile function pointer to zero memory, + * otherwise does a byte at a time write via a volatile pointer. + */ #define BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO 1 /* -* Normally blinding is performed by choosing a random starting point (plus -* its inverse, of a form appropriate to the algorithm being blinded), and -* then choosing new blinding operands by successive squaring of both -* values. This is much faster than computing a new starting point but -* introduces some possible corelation -* -* To avoid possible leakage problems in long-running processes, the blinder -* periodically reinitializes the sequence. This value specifies how often -* a new sequence should be started. -*/ + * Normally blinding is performed by choosing a random starting point (plus + * its inverse, of a form appropriate to the algorithm being blinded), and + * then choosing new blinding operands by successive squaring of both + * values. This is much faster than computing a new starting point but + * introduces some possible corelation + * + * To avoid possible leakage problems in long-running processes, the blinder + * periodically reinitializes the sequence. This value specifies how often + * a new sequence should be started. + */ #define BOTAN_BLINDING_REINIT_INTERVAL 64 /* -* Userspace RNGs like HMAC_DRBG will reseed after a specified number -* of outputs are generated. Set to zero to disable automatic reseeding. -*/ + * Userspace RNGs like HMAC_DRBG will reseed after a specified number + * of outputs are generated. Set to zero to disable automatic reseeding. + */ #define BOTAN_RNG_DEFAULT_RESEED_INTERVAL 1024 #define BOTAN_RNG_RESEED_POLL_BITS 256 @@ -215,300 +208,301 @@ #define BOTAN_RNG_RESEED_DEFAULT_TIMEOUT std::chrono::milliseconds(50) /* -* Specifies (in order) the list of entropy sources that will be used -* to seed an in-memory RNG. The first in the default list: "rdseed" -* and "rdrand" do not count as contributing any entropy but are -* included as they are fast and help protect against a seriously -* broken system RNG. -*/ -#define BOTAN_ENTROPY_DEFAULT_SOURCES \ - { "rdseed", "rdrand", "p9_darn", "getentropy", "dev_random", \ - "system_rng", "proc_walk", "system_stats" } + * Specifies (in order) the list of entropy sources that will be used + * to seed an in-memory RNG. The first in the default list: "rdseed" + * and "rdrand" do not count as contributing any entropy but are + * included as they are fast and help protect against a seriously + * broken system RNG. + */ +#define BOTAN_ENTROPY_DEFAULT_SOURCES \ + {"rdseed", "rdrand", "p9_darn", "getentropy", \ + "dev_random", "system_rng", "proc_walk", "system_stats"} /* Multiplier on a block cipher's native parallelism */ #define BOTAN_BLOCK_CIPHER_PAR_MULT 4 /* -* These control the RNG used by the system RNG interface -*/ + * These control the RNG used by the system RNG interface + */ #define BOTAN_SYSTEM_RNG_DEVICE "/dev/urandom" -#define BOTAN_SYSTEM_RNG_POLL_DEVICES { "/dev/urandom", "/dev/random" } +#define BOTAN_SYSTEM_RNG_POLL_DEVICES {"/dev/urandom", "/dev/random"} /* -* This directory will be monitored by ProcWalking_EntropySource and -* the contents provided as entropy inputs to the RNG. May also be -* usefully set to something like "/sys", depending on the system being -* deployed to. Set to an empty string to disable. -*/ + * This directory will be monitored by ProcWalking_EntropySource and + * the contents provided as entropy inputs to the RNG. May also be + * usefully set to something like "/sys", depending on the system being + * deployed to. Set to an empty string to disable. + */ #define BOTAN_ENTROPY_PROC_FS_PATH "/proc" /* -* These paramaters control how many bytes to read from the system -* PRNG, and how long to block if applicable. The timeout only applies -* to reading /dev/urandom and company. -*/ + * These paramaters control how many bytes to read from the system + * PRNG, and how long to block if applicable. The timeout only applies + * to reading /dev/urandom and company. + */ #define BOTAN_SYSTEM_RNG_POLL_REQUEST 64 #define BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS 20 /* -* When a PBKDF is self-tuning parameters, it will attempt to take about this -* amount of time to self-benchmark. -*/ + * When a PBKDF is self-tuning parameters, it will attempt to take about this + * amount of time to self-benchmark. + */ #define BOTAN_PBKDF_TUNING_TIME std::chrono::milliseconds(10) /* -* If no way of dynamically determining the cache line size for the -* system exists, this value is used as the default. Used by the side -* channel countermeasures rather than for alignment purposes, so it is -* better to be on the smaller side if the exact value cannot be -* determined. Typically 32 or 64 bytes on modern CPUs. -*/ + * If no way of dynamically determining the cache line size for the + * system exists, this value is used as the default. Used by the side + * channel countermeasures rather than for alignment purposes, so it is + * better to be on the smaller side if the exact value cannot be + * determined. Typically 32 or 64 bytes on modern CPUs. + */ #if !defined(BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE) - #define BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE 32 +#define BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE 32 #endif /** -* Controls how AutoSeeded_RNG is instantiated -*/ + * Controls how AutoSeeded_RNG is instantiated + */ #if !defined(BOTAN_AUTO_RNG_HMAC) - #if defined(BOTAN_HAS_SHA2_64) - #define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-384)" - #elif defined(BOTAN_HAS_SHA2_32) - #define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-256)" - #elif defined(BOTAN_HAS_SHA3) - #define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-3(256))" - #elif defined(BOTAN_HAS_SHA1) - #define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-1)" - #endif - /* Otherwise, no hash found: leave BOTAN_AUTO_RNG_HMAC undefined */ +#if defined(BOTAN_HAS_SHA2_64) +#define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-384)" +#elif defined(BOTAN_HAS_SHA2_32) +#define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-256)" +#elif defined(BOTAN_HAS_SHA3) +#define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-3(256))" +#elif defined(BOTAN_HAS_SHA1) +#define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-1)" +#endif +/* Otherwise, no hash found: leave BOTAN_AUTO_RNG_HMAC undefined */ #endif /* Check for a common build problem */ -#if defined(BOTAN_TARGET_ARCH_IS_X86_64) && ((defined(_MSC_VER) && !defined(_WIN64)) || \ - (defined(__clang__) && !defined(__x86_64__)) || \ - (defined(__GNUG__) && !defined(__x86_64__))) - #error "Trying to compile Botan configured as x86_64 with non-x86_64 compiler." +#if defined(BOTAN_TARGET_ARCH_IS_X86_64) && \ + ((defined(_MSC_VER) && !defined(_WIN64)) || (defined(__clang__) && !defined(__x86_64__)) || \ + (defined(__GNUG__) && !defined(__x86_64__))) +#error "Trying to compile Botan configured as x86_64 with non-x86_64 compiler." #endif -#if defined(BOTAN_TARGET_ARCH_IS_X86_32) && ((defined(_MSC_VER) && defined(_WIN64)) || \ - (defined(__clang__) && !defined(__i386__)) || \ - (defined(__GNUG__) && !defined(__i386__))) +#if defined(BOTAN_TARGET_ARCH_IS_X86_32) && \ + ((defined(_MSC_VER) && defined(_WIN64)) || (defined(__clang__) && !defined(__i386__)) || \ + (defined(__GNUG__) && !defined(__i386__))) - #error "Trying to compile Botan configured as x86_32 with non-x86_32 compiler." +#error "Trying to compile Botan configured as x86_32 with non-x86_32 compiler." #endif /* Should we use GCC-style inline assembler? */ -#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || \ - defined(BOTAN_BUILD_COMPILER_IS_CLANG) || \ - defined(BOTAN_BUILD_COMPILER_IS_XLC) || \ - defined(BOTAN_BUILD_COMPILER_IS_SUN_STUDIO) +#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || \ + defined(BOTAN_BUILD_COMPILER_IS_XLC) || defined(BOTAN_BUILD_COMPILER_IS_SUN_STUDIO) - #define BOTAN_USE_GCC_INLINE_ASM +#define BOTAN_USE_GCC_INLINE_ASM #endif /** -* Used to annotate API exports which are public and supported. -* These APIs will not be broken/removed unless strictly required for -* functionality or security, and only in new major versions. -* @param maj The major version this public API was released in -* @param min The minor version this public API was released in -*/ -#define BOTAN_PUBLIC_API(maj,min) BOTAN_DLL + * Used to annotate API exports which are public and supported. + * These APIs will not be broken/removed unless strictly required for + * functionality or security, and only in new major versions. + * @param maj The major version this public API was released in + * @param min The minor version this public API was released in + */ +#define BOTAN_PUBLIC_API(maj, min) BOTAN_DLL /** -* Used to annotate API exports which are public and can be used by -* applications if needed, but which are intentionally not documented, -* and which may change incompatibly in a future major version. -*/ + * Used to annotate API exports which are public and can be used by + * applications if needed, but which are intentionally not documented, + * and which may change incompatibly in a future major version. + */ #define BOTAN_UNSTABLE_API BOTAN_DLL /** -* Used to annotate API exports which are exported but only for the -* purposes of testing. They should not be used by applications and -* may be removed or changed without notice. -*/ + * Used to annotate API exports which are exported but only for the + * purposes of testing. They should not be used by applications and + * may be removed or changed without notice. + */ #define BOTAN_TEST_API BOTAN_DLL /* -* Define BOTAN_GCC_VERSION -*/ + * Define BOTAN_GCC_VERSION + */ #if defined(__GNUC__) && !defined(__clang__) - #define BOTAN_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__) +#define BOTAN_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__) #else - #define BOTAN_GCC_VERSION 0 +#define BOTAN_GCC_VERSION 0 #endif /* -* Define BOTAN_CLANG_VERSION -*/ + * Define BOTAN_CLANG_VERSION + */ #if defined(__clang__) - #define BOTAN_CLANG_VERSION (__clang_major__ * 10 + __clang_minor__) +#define BOTAN_CLANG_VERSION (__clang_major__ * 10 + __clang_minor__) #else - #define BOTAN_CLANG_VERSION 0 +#define BOTAN_CLANG_VERSION 0 #endif /* -* Define BOTAN_FUNC_ISA -*/ + * Define BOTAN_FUNC_ISA + */ #if (defined(__GNUC__) && !defined(__clang__)) || (BOTAN_CLANG_VERSION > 38) - #define BOTAN_FUNC_ISA(isa) __attribute__ ((target(isa))) +#define BOTAN_FUNC_ISA(isa) __attribute__((target(isa))) #else - #define BOTAN_FUNC_ISA(isa) +#define BOTAN_FUNC_ISA(isa) #endif /* -* Define BOTAN_WARN_UNUSED_RESULT -*/ + * Define BOTAN_WARN_UNUSED_RESULT + */ #if defined(__GNUC__) || defined(__clang__) - #define BOTAN_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) +#define BOTAN_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #else - #define BOTAN_WARN_UNUSED_RESULT +#define BOTAN_WARN_UNUSED_RESULT #endif /* -* Define BOTAN_MALLOC_FN -*/ + * Define BOTAN_MALLOC_FN + */ #if defined(__ibmxl__) - // XLC pretends to be both Clang and GCC, but is neither - #define BOTAN_MALLOC_FN __attribute__ ((malloc)) +// XLC pretends to be both Clang and GCC, but is neither +#define BOTAN_MALLOC_FN __attribute__((malloc)) #elif defined(__GNUC__) - #define BOTAN_MALLOC_FN __attribute__ ((malloc, alloc_size(1,2))) +#define BOTAN_MALLOC_FN __attribute__((malloc, alloc_size(1, 2))) #elif defined(_MSC_VER) - #define BOTAN_MALLOC_FN __declspec(restrict) +#define BOTAN_MALLOC_FN __declspec(restrict) #else - #define BOTAN_MALLOC_FN +#define BOTAN_MALLOC_FN #endif /* -* Define BOTAN_DEPRECATED -*/ + * Define BOTAN_DEPRECATED + */ #if !defined(BOTAN_NO_DEPRECATED_WARNINGS) - #if defined(__clang__) - #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg))) - #define BOTAN_DEPRECATED_HEADER(hdr) _Pragma("message \"this header is deprecated\"") +#if defined(__clang__) +#define BOTAN_DEPRECATED(msg) __attribute__((deprecated(msg))) +#define BOTAN_DEPRECATED_HEADER(hdr) _Pragma("message \"this header is deprecated\"") - #if !defined(BOTAN_IS_BEING_BUILT) - #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) _Pragma("message \"this header will be made internal in the future\"") - #endif +#if !defined(BOTAN_IS_BEING_BUILT) +#define BOTAN_FUTURE_INTERNAL_HEADER(hdr) \ + _Pragma("message \"this header will be made internal in the future\"") +#endif - #elif defined(_MSC_VER) - #define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg)) - #define BOTAN_DEPRECATED_HEADER(hdr) __pragma(message("this header is deprecated")) +#elif defined(_MSC_VER) +#define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg)) +#define BOTAN_DEPRECATED_HEADER(hdr) __pragma(message("this header is deprecated")) - #if !defined(BOTAN_IS_BEING_BUILT) - #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) __pragma(message("this header will be made internal in the future")) - #endif +#if !defined(BOTAN_IS_BEING_BUILT) +#define BOTAN_FUTURE_INTERNAL_HEADER(hdr) \ + __pragma(message("this header will be made internal in the future")) +#endif - #elif defined(__GNUC__) - /* msg supported since GCC 4.5, earliest we support is 4.8 */ - #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg))) - #define BOTAN_DEPRECATED_HEADER(hdr) _Pragma("GCC warning \"this header is deprecated\"") +#elif defined(__GNUC__) +/* msg supported since GCC 4.5, earliest we support is 4.8 */ +#define BOTAN_DEPRECATED(msg) __attribute__((deprecated(msg))) +#define BOTAN_DEPRECATED_HEADER(hdr) _Pragma("GCC warning \"this header is deprecated\"") - #if !defined(BOTAN_IS_BEING_BUILT) - #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) _Pragma("GCC warning \"this header will be made internal in the future\"") - #endif - #endif +#if !defined(BOTAN_IS_BEING_BUILT) +#define BOTAN_FUTURE_INTERNAL_HEADER(hdr) \ + _Pragma("GCC warning \"this header will be made internal in the future\"") +#endif +#endif #endif #if !defined(BOTAN_DEPRECATED) - #define BOTAN_DEPRECATED(msg) +#define BOTAN_DEPRECATED(msg) #endif #if !defined(BOTAN_DEPRECATED_HEADER) - #define BOTAN_DEPRECATED_HEADER(hdr) +#define BOTAN_DEPRECATED_HEADER(hdr) #endif #if !defined(BOTAN_FUTURE_INTERNAL_HEADER) - #define BOTAN_FUTURE_INTERNAL_HEADER(hdr) +#define BOTAN_FUTURE_INTERNAL_HEADER(hdr) #endif /* -* Define BOTAN_NORETURN -*/ + * Define BOTAN_NORETURN + */ #if !defined(BOTAN_NORETURN) - #if defined (__clang__) || defined (__GNUC__) - #define BOTAN_NORETURN __attribute__ ((__noreturn__)) +#if defined(__clang__) || defined(__GNUC__) +#define BOTAN_NORETURN __attribute__((__noreturn__)) - #elif defined (_MSC_VER) - #define BOTAN_NORETURN __declspec(noreturn) +#elif defined(_MSC_VER) +#define BOTAN_NORETURN __declspec(noreturn) - #else - #define BOTAN_NORETURN - #endif +#else +#define BOTAN_NORETURN +#endif #endif /* -* Define BOTAN_THREAD_LOCAL -*/ + * Define BOTAN_THREAD_LOCAL + */ #if !defined(BOTAN_THREAD_LOCAL) - #if defined(BOTAN_TARGET_OS_HAS_THREADS) && defined(BOTAN_TARGET_OS_HAS_THREAD_LOCAL) - #define BOTAN_THREAD_LOCAL thread_local - #else - #define BOTAN_THREAD_LOCAL /**/ - #endif +#if defined(BOTAN_TARGET_OS_HAS_THREADS) && defined(BOTAN_TARGET_OS_HAS_THREAD_LOCAL) +#define BOTAN_THREAD_LOCAL thread_local +#else +#define BOTAN_THREAD_LOCAL /**/ +#endif #endif /* -* Define BOTAN_IF_CONSTEXPR -*/ + * Define BOTAN_IF_CONSTEXPR + */ #if !defined(BOTAN_IF_CONSTEXPR) - #if __cplusplus > 201402 - #define BOTAN_IF_CONSTEXPR if constexpr - #else - #define BOTAN_IF_CONSTEXPR if - #endif +#if __cplusplus > 201402 +#define BOTAN_IF_CONSTEXPR if constexpr +#else +#define BOTAN_IF_CONSTEXPR if +#endif #endif /* -* Define BOTAN_PARALLEL_FOR -*/ + * Define BOTAN_PARALLEL_FOR + */ #if !defined(BOTAN_PARALLEL_FOR) #if defined(BOTAN_TARGET_HAS_OPENMP) - #define BOTAN_PARALLEL_FOR _Pragma("omp parallel for") for +#define BOTAN_PARALLEL_FOR _Pragma("omp parallel for") for #else - #define BOTAN_PARALLEL_FOR for +#define BOTAN_PARALLEL_FOR for #endif #endif /* -* Define BOTAN_FORCE_INLINE -*/ + * Define BOTAN_FORCE_INLINE + */ #if !defined(BOTAN_FORCE_INLINE) - #if defined (__clang__) || defined (__GNUC__) - #define BOTAN_FORCE_INLINE __attribute__ ((__always_inline__)) inline +#if defined(__clang__) || defined(__GNUC__) +#define BOTAN_FORCE_INLINE __attribute__((__always_inline__)) inline - #elif defined (_MSC_VER) - #define BOTAN_FORCE_INLINE __forceinline +#elif defined(_MSC_VER) +#define BOTAN_FORCE_INLINE __forceinline - #else - #define BOTAN_FORCE_INLINE inline - #endif +#else +#define BOTAN_FORCE_INLINE inline +#endif #endif /* -* Define BOTAN_PARALLEL_SIMD_FOR -*/ + * Define BOTAN_PARALLEL_SIMD_FOR + */ #if !defined(BOTAN_PARALLEL_SIMD_FOR) #if defined(BOTAN_TARGET_HAS_OPENMP) - #define BOTAN_PARALLEL_SIMD_FOR _Pragma("omp simd") for +#define BOTAN_PARALLEL_SIMD_FOR _Pragma("omp simd") for #elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 490) - #define BOTAN_PARALLEL_SIMD_FOR _Pragma("GCC ivdep") for +#define BOTAN_PARALLEL_SIMD_FOR _Pragma("GCC ivdep") for #else - #define BOTAN_PARALLEL_SIMD_FOR for +#define BOTAN_PARALLEL_SIMD_FOR for #endif #endif @@ -516,104 +510,82 @@ namespace Botan { /** -* Called when an assertion fails -* Throws an Exception object -*/ -BOTAN_NORETURN void BOTAN_PUBLIC_API(2,0) - assertion_failure(const char* expr_str, - const char* assertion_made, - const char* func, - const char* file, - int line); + * Called when an assertion fails + * Throws an Exception object + */ +BOTAN_NORETURN void BOTAN_PUBLIC_API(2, 0) + assertion_failure(const char* expr_str, const char* assertion_made, const char* func, + const char* file, int line); /** -* Called when an invalid argument is used -* Throws Invalid_Argument -*/ -BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_argument(const char* message, - const char* func, + * Called when an invalid argument is used + * Throws Invalid_Argument + */ +BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_argument(const char* message, const char* func, const char* file); - -#define BOTAN_ARG_CHECK(expr, msg) \ - do { if(!(expr)) Botan::throw_invalid_argument(msg, __func__, __FILE__); } while(0) +#define BOTAN_ARG_CHECK(expr, msg) \ + do { \ + if (!(expr)) Botan::throw_invalid_argument(msg, __func__, __FILE__); \ + } while (0) /** -* Called when an invalid state is encountered -* Throws Invalid_State -*/ -BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_state(const char* message, - const char* func, + * Called when an invalid state is encountered + * Throws Invalid_State + */ +BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_state(const char* message, const char* func, const char* file); - -#define BOTAN_STATE_CHECK(expr) \ - do { if(!(expr)) Botan::throw_invalid_state(#expr, __func__, __FILE__); } while(0) +#define BOTAN_STATE_CHECK(expr) \ + do { \ + if (!(expr)) Botan::throw_invalid_state(#expr, __func__, __FILE__); \ + } while (0) /** -* Make an assertion -*/ -#define BOTAN_ASSERT(expr, assertion_made) \ - do { \ - if(!(expr)) \ - Botan::assertion_failure(#expr, \ - assertion_made, \ - __func__, \ - __FILE__, \ - __LINE__); \ - } while(0) + * Make an assertion + */ +#define BOTAN_ASSERT(expr, assertion_made) \ + do { \ + if (!(expr)) \ + Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \ + } while (0) /** -* Make an assertion -*/ -#define BOTAN_ASSERT_NOMSG(expr) \ - do { \ - if(!(expr)) \ - Botan::assertion_failure(#expr, \ - "", \ - __func__, \ - __FILE__, \ - __LINE__); \ - } while(0) + * Make an assertion + */ +#define BOTAN_ASSERT_NOMSG(expr) \ + do { \ + if (!(expr)) Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \ + } while (0) /** -* Assert that value1 == value2 -*/ -#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made) \ - do { \ - if((expr1) != (expr2)) \ - Botan::assertion_failure(#expr1 " == " #expr2, \ - assertion_made, \ - __func__, \ - __FILE__, \ - __LINE__); \ - } while(0) + * Assert that value1 == value2 + */ +#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made) \ + do { \ + if ((expr1) != (expr2)) \ + Botan::assertion_failure(#expr1 " == " #expr2, assertion_made, __func__, __FILE__, \ + __LINE__); \ + } while (0) /** -* Assert that expr1 (if true) implies expr2 is also true -*/ -#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg) \ - do { \ - if((expr1) && !(expr2)) \ - Botan::assertion_failure(#expr1 " implies " #expr2, \ - msg, \ - __func__, \ - __FILE__, \ - __LINE__); \ - } while(0) + * Assert that expr1 (if true) implies expr2 is also true + */ +#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg) \ + do { \ + if ((expr1) && !(expr2)) \ + Botan::assertion_failure(#expr1 " implies " #expr2, msg, __func__, __FILE__, \ + __LINE__); \ + } while (0) /** -* Assert that a pointer is not null -*/ -#define BOTAN_ASSERT_NONNULL(ptr) \ - do { \ - if((ptr) == nullptr) \ - Botan::assertion_failure(#ptr " is not null", \ - "", \ - __func__, \ - __FILE__, \ - __LINE__); \ - } while(0) + * Assert that a pointer is not null + */ +#define BOTAN_ASSERT_NONNULL(ptr) \ + do { \ + if ((ptr) == nullptr) \ + Botan::assertion_failure(#ptr " is not null", "", __func__, __FILE__, __LINE__); \ + } while (0) #if defined(BOTAN_ENABLE_DEBUG_ASSERTS) @@ -621,1623 +593,1476 @@ BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_state(const char* message, #else -#define BOTAN_DEBUG_ASSERT(expr) do {} while(0) +#define BOTAN_DEBUG_ASSERT(expr) \ + do { \ + } while (0) #endif /** -* Mark variable as unused. Takes between 1 and 9 arguments and marks all as unused, -* e.g. BOTAN_UNUSED(a); or BOTAN_UNUSED(x, y, z); -*/ -#define _BOTAN_UNUSED_IMPL1(a) static_cast(a) -#define _BOTAN_UNUSED_IMPL2(a, b) static_cast(a); _BOTAN_UNUSED_IMPL1(b) -#define _BOTAN_UNUSED_IMPL3(a, b, c) static_cast(a); _BOTAN_UNUSED_IMPL2(b, c) -#define _BOTAN_UNUSED_IMPL4(a, b, c, d) static_cast(a); _BOTAN_UNUSED_IMPL3(b, c, d) -#define _BOTAN_UNUSED_IMPL5(a, b, c, d, e) static_cast(a); _BOTAN_UNUSED_IMPL4(b, c, d, e) -#define _BOTAN_UNUSED_IMPL6(a, b, c, d, e, f) static_cast(a); _BOTAN_UNUSED_IMPL5(b, c, d, e, f) -#define _BOTAN_UNUSED_IMPL7(a, b, c, d, e, f, g) static_cast(a); _BOTAN_UNUSED_IMPL6(b, c, d, e, f, g) -#define _BOTAN_UNUSED_IMPL8(a, b, c, d, e, f, g, h) static_cast(a); _BOTAN_UNUSED_IMPL7(b, c, d, e, f, g, h) -#define _BOTAN_UNUSED_IMPL9(a, b, c, d, e, f, g, h, i) static_cast(a); _BOTAN_UNUSED_IMPL8(b, c, d, e, f, g, h, i) + * Mark variable as unused. Takes between 1 and 9 arguments and marks all as unused, + * e.g. BOTAN_UNUSED(a); or BOTAN_UNUSED(x, y, z); + */ +#define _BOTAN_UNUSED_IMPL1(a) static_cast(a) +#define _BOTAN_UNUSED_IMPL2(a, b) \ + static_cast(a); \ + _BOTAN_UNUSED_IMPL1(b) +#define _BOTAN_UNUSED_IMPL3(a, b, c) \ + static_cast(a); \ + _BOTAN_UNUSED_IMPL2(b, c) +#define _BOTAN_UNUSED_IMPL4(a, b, c, d) \ + static_cast(a); \ + _BOTAN_UNUSED_IMPL3(b, c, d) +#define _BOTAN_UNUSED_IMPL5(a, b, c, d, e) \ + static_cast(a); \ + _BOTAN_UNUSED_IMPL4(b, c, d, e) +#define _BOTAN_UNUSED_IMPL6(a, b, c, d, e, f) \ + static_cast(a); \ + _BOTAN_UNUSED_IMPL5(b, c, d, e, f) +#define _BOTAN_UNUSED_IMPL7(a, b, c, d, e, f, g) \ + static_cast(a); \ + _BOTAN_UNUSED_IMPL6(b, c, d, e, f, g) +#define _BOTAN_UNUSED_IMPL8(a, b, c, d, e, f, g, h) \ + static_cast(a); \ + _BOTAN_UNUSED_IMPL7(b, c, d, e, f, g, h) +#define _BOTAN_UNUSED_IMPL9(a, b, c, d, e, f, g, h, i) \ + static_cast(a); \ + _BOTAN_UNUSED_IMPL8(b, c, d, e, f, g, h, i) #define _BOTAN_UNUSED_GET_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, IMPL_NAME, ...) IMPL_NAME -#define BOTAN_UNUSED(...) _BOTAN_UNUSED_GET_IMPL(__VA_ARGS__, \ - _BOTAN_UNUSED_IMPL9, \ - _BOTAN_UNUSED_IMPL8, \ - _BOTAN_UNUSED_IMPL7, \ - _BOTAN_UNUSED_IMPL6, \ - _BOTAN_UNUSED_IMPL5, \ - _BOTAN_UNUSED_IMPL4, \ - _BOTAN_UNUSED_IMPL3, \ - _BOTAN_UNUSED_IMPL2, \ - _BOTAN_UNUSED_IMPL1, \ - unused dummy rest value \ - ) /* we got an one of _BOTAN_UNUSED_IMPL*, now call it */ (__VA_ARGS__) +#define BOTAN_UNUSED(...) \ + _BOTAN_UNUSED_GET_IMPL(__VA_ARGS__, _BOTAN_UNUSED_IMPL9, _BOTAN_UNUSED_IMPL8, \ + _BOTAN_UNUSED_IMPL7, _BOTAN_UNUSED_IMPL6, _BOTAN_UNUSED_IMPL5, \ + _BOTAN_UNUSED_IMPL4, _BOTAN_UNUSED_IMPL3, _BOTAN_UNUSED_IMPL2, \ + _BOTAN_UNUSED_IMPL1, unused dummy rest value) \ + /* we got an one of _BOTAN_UNUSED_IMPL*, now call it */ (__VA_ARGS__) -} +} // namespace Botan namespace Botan { /** -* @mainpage Botan Crypto Library API Reference -* -*
-*
Abstract Base Classes
-* BlockCipher, HashFunction, KDF, MessageAuthenticationCode, RandomNumberGenerator, -* StreamCipher, SymmetricAlgorithm, AEAD_Mode, Cipher_Mode -*
Public Key Interface Classes
-* PK_Key_Agreement, PK_Signer, PK_Verifier, PK_Encryptor, PK_Decryptor -*
Authenticated Encryption Modes
-* @ref CCM_Mode "CCM", @ref ChaCha20Poly1305_Mode "ChaCha20Poly1305", @ref EAX_Mode "EAX", -* @ref GCM_Mode "GCM", @ref OCB_Mode "OCB", @ref SIV_Mode "SIV" -*
Block Ciphers
-* @ref aria.h "ARIA", @ref aes.h "AES", @ref Blowfish, @ref camellia.h "Camellia", @ref Cascade_Cipher "Cascade", -* @ref CAST_128 "CAST-128", @ref CAST_128 "CAST-256", DES, @ref DESX "DES-X", @ref TripleDES "3DES", -* @ref GOST_28147_89 "GOST 28147-89", IDEA, KASUMI, Lion, MISTY1, Noekeon, SEED, Serpent, SHACAL2, SM4, -* @ref Threefish_512 "Threefish", Twofish, XTEA -*
Stream Ciphers
-* ChaCha, @ref CTR_BE "CTR", OFB, RC4, Salsa20 -*
Hash Functions
-* Blake2b, @ref GOST_34_11 "GOST 34.11", @ref Keccak_1600 "Keccak", MD4, MD5, @ref RIPEMD_160 "RIPEMD-160", -* @ref SHA_160 "SHA-1", @ref SHA_224 "SHA-224", @ref SHA_256 "SHA-256", @ref SHA_384 "SHA-384", -* @ref SHA_512 "SHA-512", @ref Skein_512 "Skein-512", SM3, Streebog, Tiger, Whirlpool -*
Non-Cryptographic Checksums
-* Adler32, CRC24, CRC32 -*
Message Authentication Codes
-* @ref CBC_MAC "CBC-MAC", CMAC, HMAC, Poly1305, SipHash, ANSI_X919_MAC -*
Random Number Generators
-* AutoSeeded_RNG, HMAC_DRBG, RDRAND_RNG, System_RNG -*
Key Derivation
-* HKDF, @ref KDF1 "KDF1 (IEEE 1363)", @ref KDF1_18033 "KDF1 (ISO 18033-2)", @ref KDF2 "KDF2 (IEEE 1363)", -* @ref sp800_108.h "SP800-108", @ref SP800_56C "SP800-56C", @ref PKCS5_PBKDF1 "PBKDF1 (PKCS#5), -* @ref PKCS5_PBKDF2 "PBKDF2 (PKCS#5)" -*
Password Hashing
-* @ref bcrypt.h "bcrypt", @ref passhash9.h "passhash9" -*
Public Key Cryptosystems
-* @ref dlies.h "DLIES", @ref ecies.h "ECIES", @ref elgamal.h "ElGamal" -* @ref rsa.h "RSA", @ref newhope.h "NewHope", @ref mceliece.h "McEliece" and @ref mceies.h "MCEIES", -* @ref sm2.h "SM2" -*
Public Key Signature Schemes
-* @ref dsa.h "DSA", @ref ecdsa.h "ECDSA", @ref ecgdsa.h "ECGDSA", @ref eckcdsa.h "ECKCDSA", -* @ref gost_3410.h "GOST 34.10-2001", @ref sm2.h "SM2", @ref xmss.h "XMSS" -*
Key Agreement
-* @ref dh.h "DH", @ref ecdh.h "ECDH" -*
Compression
-* @ref bzip2.h "bzip2", @ref lzma.h "lzma", @ref zlib.h "zlib" -*
TLS
-* TLS::Client, TLS::Server, TLS::Policy, TLS::Protocol_Version, TLS::Callbacks, TLS::Ciphersuite, -* TLS::Session, TLS::Session_Manager, Credentials_Manager -*
X.509
-* X509_Certificate, X509_CRL, X509_CA, Certificate_Extension, PKCS10_Request, X509_Cert_Options, -* Certificate_Store, Certificate_Store_In_SQL, Certificate_Store_In_SQLite -*
-*/ + * @mainpage Botan Crypto Library API Reference + * + *
+ *
Abstract Base Classes
+ * BlockCipher, HashFunction, KDF, MessageAuthenticationCode, RandomNumberGenerator, + * StreamCipher, SymmetricAlgorithm, AEAD_Mode, Cipher_Mode + *
Public Key Interface Classes
+ * PK_Key_Agreement, PK_Signer, PK_Verifier, PK_Encryptor, PK_Decryptor + *
Authenticated Encryption Modes
+ * @ref CCM_Mode "CCM", @ref ChaCha20Poly1305_Mode "ChaCha20Poly1305", @ref EAX_Mode "EAX", + * @ref GCM_Mode "GCM", @ref OCB_Mode "OCB", @ref SIV_Mode "SIV" + *
Block Ciphers
+ * @ref aria.h "ARIA", @ref aes.h "AES", @ref Blowfish, @ref camellia.h "Camellia", @ref + * Cascade_Cipher "Cascade", + * @ref CAST_128 "CAST-128", @ref CAST_128 "CAST-256", DES, @ref DESX "DES-X", @ref TripleDES + * "3DES", + * @ref GOST_28147_89 "GOST 28147-89", IDEA, KASUMI, Lion, MISTY1, Noekeon, SEED, Serpent, + * SHACAL2, SM4, + * @ref Threefish_512 "Threefish", Twofish, XTEA + *
Stream Ciphers
+ * ChaCha, @ref CTR_BE "CTR", OFB, RC4, Salsa20 + *
Hash Functions
+ * Blake2b, @ref GOST_34_11 "GOST 34.11", @ref Keccak_1600 "Keccak", MD4, MD5, @ref + * RIPEMD_160 "RIPEMD-160", + * @ref SHA_160 "SHA-1", @ref SHA_224 "SHA-224", @ref SHA_256 "SHA-256", @ref SHA_384 + * "SHA-384", + * @ref SHA_512 "SHA-512", @ref Skein_512 "Skein-512", SM3, Streebog, Tiger, Whirlpool + *
Non-Cryptographic Checksums
+ * Adler32, CRC24, CRC32 + *
Message Authentication Codes
+ * @ref CBC_MAC "CBC-MAC", CMAC, HMAC, Poly1305, SipHash, ANSI_X919_MAC + *
Random Number Generators
+ * AutoSeeded_RNG, HMAC_DRBG, RDRAND_RNG, System_RNG + *
Key Derivation
+ * HKDF, @ref KDF1 "KDF1 (IEEE 1363)", @ref KDF1_18033 "KDF1 (ISO 18033-2)", @ref KDF2 "KDF2 + * (IEEE 1363)", + * @ref sp800_108.h "SP800-108", @ref SP800_56C "SP800-56C", @ref PKCS5_PBKDF1 "PBKDF1 + * (PKCS#5), + * @ref PKCS5_PBKDF2 "PBKDF2 (PKCS#5)" + *
Password Hashing
+ * @ref bcrypt.h "bcrypt", @ref passhash9.h "passhash9" + *
Public Key Cryptosystems
+ * @ref dlies.h "DLIES", @ref ecies.h "ECIES", @ref elgamal.h "ElGamal" + * @ref rsa.h "RSA", @ref newhope.h "NewHope", @ref mceliece.h "McEliece" and @ref mceies.h + * "MCEIES", + * @ref sm2.h "SM2" + *
Public Key Signature Schemes
+ * @ref dsa.h "DSA", @ref ecdsa.h "ECDSA", @ref ecgdsa.h "ECGDSA", @ref eckcdsa.h "ECKCDSA", + * @ref gost_3410.h "GOST 34.10-2001", @ref sm2.h "SM2", @ref xmss.h "XMSS" + *
Key Agreement
+ * @ref dh.h "DH", @ref ecdh.h "ECDH" + *
Compression
+ * @ref bzip2.h "bzip2", @ref lzma.h "lzma", @ref zlib.h "zlib" + *
TLS
+ * TLS::Client, TLS::Server, TLS::Policy, TLS::Protocol_Version, TLS::Callbacks, + * TLS::Ciphersuite, TLS::Session, TLS::Session_Manager, Credentials_Manager
X.509
+ * X509_Certificate, X509_CRL, X509_CA, Certificate_Extension, PKCS10_Request, + * X509_Cert_Options, Certificate_Store, Certificate_Store_In_SQL, Certificate_Store_In_SQLite + *
+ */ -using std::uint8_t; -using std::uint16_t; -using std::uint32_t; -using std::uint64_t; using std::int32_t; using std::int64_t; using std::size_t; +using std::uint16_t; +using std::uint32_t; +using std::uint64_t; +using std::uint8_t; /* -* These typedefs are no longer used within the library headers -* or code. They are kept only for compatability with software -* written against older versions. -*/ -using byte = std::uint8_t; + * These typedefs are no longer used within the library headers + * or code. They are kept only for compatability with software + * written against older versions. + */ +using byte = std::uint8_t; using u16bit = std::uint16_t; using u32bit = std::uint32_t; using u64bit = std::uint64_t; using s32bit = std::int32_t; #if (BOTAN_MP_WORD_BITS == 32) - typedef uint32_t word; +typedef uint32_t word; #elif (BOTAN_MP_WORD_BITS == 64) - typedef uint64_t word; +typedef uint64_t word; #else - #error BOTAN_MP_WORD_BITS must be 32 or 64 +#error BOTAN_MP_WORD_BITS must be 32 or 64 #endif -} +} // namespace Botan namespace Botan { /** -* Represents the length requirements on an algorithm key -*/ -class BOTAN_PUBLIC_API(2,0) Key_Length_Specification final - { + * Represents the length requirements on an algorithm key + */ +class BOTAN_PUBLIC_API(2, 0) Key_Length_Specification final { public: - /** - * Constructor for fixed length keys - * @param keylen the supported key length - */ - explicit Key_Length_Specification(size_t keylen) : - m_min_keylen(keylen), - m_max_keylen(keylen), - m_keylen_mod(1) - { - } + /** + * Constructor for fixed length keys + * @param keylen the supported key length + */ + explicit Key_Length_Specification(size_t keylen) + : m_min_keylen(keylen), m_max_keylen(keylen), m_keylen_mod(1) {} - /** - * Constructor for variable length keys - * @param min_k the smallest supported key length - * @param max_k the largest supported key length - * @param k_mod the number of bytes the key must be a multiple of - */ - Key_Length_Specification(size_t min_k, - size_t max_k, - size_t k_mod = 1) : - m_min_keylen(min_k), - m_max_keylen(max_k ? max_k : min_k), - m_keylen_mod(k_mod) - { - } + /** + * Constructor for variable length keys + * @param min_k the smallest supported key length + * @param max_k the largest supported key length + * @param k_mod the number of bytes the key must be a multiple of + */ + Key_Length_Specification(size_t min_k, size_t max_k, size_t k_mod = 1) + : m_min_keylen(min_k), m_max_keylen(max_k ? max_k : min_k), m_keylen_mod(k_mod) {} - /** - * @param length is a key length in bytes - * @return true iff this length is a valid length for this algo - */ - bool valid_keylength(size_t length) const - { - return ((length >= m_min_keylen) && - (length <= m_max_keylen) && - (length % m_keylen_mod == 0)); - } + /** + * @param length is a key length in bytes + * @return true iff this length is a valid length for this algo + */ + bool valid_keylength(size_t length) const { + return ((length >= m_min_keylen) && (length <= m_max_keylen) && + (length % m_keylen_mod == 0)); + } - /** - * @return minimum key length in bytes - */ - size_t minimum_keylength() const - { - return m_min_keylen; - } + /** + * @return minimum key length in bytes + */ + size_t minimum_keylength() const { return m_min_keylen; } - /** - * @return maximum key length in bytes - */ - size_t maximum_keylength() const - { - return m_max_keylen; - } + /** + * @return maximum key length in bytes + */ + size_t maximum_keylength() const { return m_max_keylen; } - /** - * @return key length multiple in bytes - */ - size_t keylength_multiple() const - { - return m_keylen_mod; - } + /** + * @return key length multiple in bytes + */ + size_t keylength_multiple() const { return m_keylen_mod; } - /* - * Multiplies all length requirements with the given factor - * @param n the multiplication factor - * @return a key length specification multiplied by the factor - */ - Key_Length_Specification multiple(size_t n) const - { - return Key_Length_Specification(n * m_min_keylen, - n * m_max_keylen, - n * m_keylen_mod); - } + /* + * Multiplies all length requirements with the given factor + * @param n the multiplication factor + * @return a key length specification multiplied by the factor + */ + Key_Length_Specification multiple(size_t n) const { + return Key_Length_Specification(n * m_min_keylen, n * m_max_keylen, n * m_keylen_mod); + } private: - size_t m_min_keylen, m_max_keylen, m_keylen_mod; - }; + size_t m_min_keylen, m_max_keylen, m_keylen_mod; +}; -} +} // namespace Botan namespace Botan { /** -* Allocate a memory buffer by some method. This should only be used for -* primitive types (uint8_t, uint32_t, etc). -* -* @param elems the number of elements -* @param elem_size the size of each element -* @return pointer to allocated and zeroed memory, or throw std::bad_alloc on failure -*/ -BOTAN_PUBLIC_API(2,3) BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t elem_size); + * Allocate a memory buffer by some method. This should only be used for + * primitive types (uint8_t, uint32_t, etc). + * + * @param elems the number of elements + * @param elem_size the size of each element + * @return pointer to allocated and zeroed memory, or throw std::bad_alloc on failure + */ +BOTAN_PUBLIC_API(2, 3) BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t elem_size); /** -* Free a pointer returned by allocate_memory -* @param p the pointer returned by allocate_memory -* @param elems the number of elements, as passed to allocate_memory -* @param elem_size the size of each element, as passed to allocate_memory -*/ -BOTAN_PUBLIC_API(2,3) void deallocate_memory(void* p, size_t elems, size_t elem_size); + * Free a pointer returned by allocate_memory + * @param p the pointer returned by allocate_memory + * @param elems the number of elements, as passed to allocate_memory + * @param elem_size the size of each element, as passed to allocate_memory + */ +BOTAN_PUBLIC_API(2, 3) void deallocate_memory(void* p, size_t elems, size_t elem_size); /** -* Ensure the allocator is initialized -*/ + * Ensure the allocator is initialized + */ void initialize_allocator(); -class Allocator_Initializer - { +class Allocator_Initializer { public: - Allocator_Initializer() { initialize_allocator(); } - }; + Allocator_Initializer() { initialize_allocator(); } +}; /** -* Scrub memory contents in a way that a compiler should not elide, -* using some system specific technique. Note that this function might -* not zero the memory (for example, in some hypothetical -* implementation it might combine the memory contents with the output -* of a system PRNG), but if you can detect any difference in behavior -* at runtime then the clearing is side-effecting and you can just -* use `clear_mem`. -* -* Use this function to scrub memory just before deallocating it, or on -* a stack buffer before returning from the function. -* -* @param ptr a pointer to memory to scrub -* @param n the number of bytes pointed to by ptr -*/ -BOTAN_PUBLIC_API(2,0) void secure_scrub_memory(void* ptr, size_t n); + * Scrub memory contents in a way that a compiler should not elide, + * using some system specific technique. Note that this function might + * not zero the memory (for example, in some hypothetical + * implementation it might combine the memory contents with the output + * of a system PRNG), but if you can detect any difference in behavior + * at runtime then the clearing is side-effecting and you can just + * use `clear_mem`. + * + * Use this function to scrub memory just before deallocating it, or on + * a stack buffer before returning from the function. + * + * @param ptr a pointer to memory to scrub + * @param n the number of bytes pointed to by ptr + */ +BOTAN_PUBLIC_API(2, 0) void secure_scrub_memory(void* ptr, size_t n); /** -* Memory comparison, input insensitive -* @param x a pointer to an array -* @param y a pointer to another array -* @param len the number of Ts in x and y -* @return 0xFF iff x[i] == y[i] forall i in [0...n) or 0x00 otherwise -*/ -BOTAN_PUBLIC_API(2,9) uint8_t ct_compare_u8(const uint8_t x[], - const uint8_t y[], - size_t len); + * Memory comparison, input insensitive + * @param x a pointer to an array + * @param y a pointer to another array + * @param len the number of Ts in x and y + * @return 0xFF iff x[i] == y[i] forall i in [0...n) or 0x00 otherwise + */ +BOTAN_PUBLIC_API(2, 9) uint8_t ct_compare_u8(const uint8_t x[], const uint8_t y[], size_t len); /** -* Memory comparison, input insensitive -* @param x a pointer to an array -* @param y a pointer to another array -* @param len the number of Ts in x and y -* @return true iff x[i] == y[i] forall i in [0...n) -*/ -inline bool constant_time_compare(const uint8_t x[], - const uint8_t y[], - size_t len) - { - return ct_compare_u8(x, y, len) == 0xFF; - } - -/** -* Zero out some bytes -* @param ptr a pointer to memory to zero -* @param bytes the number of bytes to zero in ptr -*/ -inline void clear_bytes(void* ptr, size_t bytes) - { - if(bytes > 0) - { - std::memset(ptr, 0, bytes); - } - } - -/** -* Zero memory before use. This simply calls memset and should not be -* used in cases where the compiler cannot see the call as a -* side-effecting operation (for example, if calling clear_mem before -* deallocating memory, the compiler would be allowed to omit the call -* to memset entirely under the as-if rule.) -* -* @param ptr a pointer to an array of Ts to zero -* @param n the number of Ts pointed to by ptr -*/ -template inline void clear_mem(T* ptr, size_t n) - { - clear_bytes(ptr, sizeof(T)*n); - } - -/** -* Copy memory -* @param out the destination array -* @param in the source array -* @param n the number of elements of in/out -*/ -template inline void copy_mem(T* out, const T* in, size_t n) - { - if(n > 0) - { - std::memmove(out, in, sizeof(T)*n); - } - } - -template inline void typecast_copy(uint8_t out[], T in[], size_t N) - { - std::memcpy(out, in, sizeof(T)*N); - } - -template inline void typecast_copy(T out[], const uint8_t in[], size_t N) - { - std::memcpy(out, in, sizeof(T)*N); - } - -template inline void typecast_copy(uint8_t out[], T in) - { - typecast_copy(out, &in, 1); - } - -template inline void typecast_copy(T& out, const uint8_t in[]) - { - typecast_copy(&out, in, 1); - } - -/** -* Set memory to a fixed value -* @param ptr a pointer to an array of bytes -* @param n the number of Ts pointed to by ptr -* @param val the value to set each byte to -*/ -inline void set_mem(uint8_t* ptr, size_t n, uint8_t val) - { - if(n > 0) - { - std::memset(ptr, val, n); - } - } - -inline const uint8_t* cast_char_ptr_to_uint8(const char* s) - { - return reinterpret_cast(s); - } - -inline const char* cast_uint8_ptr_to_char(const uint8_t* b) - { - return reinterpret_cast(b); - } - -inline uint8_t* cast_char_ptr_to_uint8(char* s) - { - return reinterpret_cast(s); - } - -inline char* cast_uint8_ptr_to_char(uint8_t* b) - { - return reinterpret_cast(b); - } - -/** -* Memory comparison, input insensitive -* @param p1 a pointer to an array -* @param p2 a pointer to another array -* @param n the number of Ts in p1 and p2 -* @return true iff p1[i] == p2[i] forall i in [0...n) -*/ -template inline bool same_mem(const T* p1, const T* p2, size_t n) - { - volatile T difference = 0; - - for(size_t i = 0; i != n; ++i) - difference |= (p1[i] ^ p2[i]); - - return difference == 0; - } - -/** -* XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length -* @param out the input/output buffer -* @param in the read-only input buffer -* @param length the length of the buffers -*/ -inline void xor_buf(uint8_t out[], - const uint8_t in[], - size_t length) - { - const size_t blocks = length - (length % 32); - - for(size_t i = 0; i != blocks; i += 32) - { - uint64_t x[4]; - uint64_t y[4]; - - typecast_copy(x, out + i, 4); - typecast_copy(y, in + i, 4); - - x[0] ^= y[0]; - x[1] ^= y[1]; - x[2] ^= y[2]; - x[3] ^= y[3]; - - typecast_copy(out + i, x, 4); - } - - for(size_t i = blocks; i != length; ++i) - { - out[i] ^= in[i]; - } - } - -/** -* XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length -* @param out the output buffer -* @param in the first input buffer -* @param in2 the second output buffer -* @param length the length of the three buffers -*/ -inline void xor_buf(uint8_t out[], - const uint8_t in[], - const uint8_t in2[], - size_t length) - { - const size_t blocks = length - (length % 32); - - for(size_t i = 0; i != blocks; i += 32) - { - uint64_t x[4]; - uint64_t y[4]; - - typecast_copy(x, in + i, 4); - typecast_copy(y, in2 + i, 4); - - x[0] ^= y[0]; - x[1] ^= y[1]; - x[2] ^= y[2]; - x[3] ^= y[3]; - - typecast_copy(out + i, x, 4); - } - - for(size_t i = blocks; i != length; ++i) - { - out[i] = in[i] ^ in2[i]; - } - } - -template -void xor_buf(std::vector& out, - const std::vector& in, - size_t n) - { - xor_buf(out.data(), in.data(), n); - } - -template -void xor_buf(std::vector& out, - const uint8_t* in, - size_t n) - { - xor_buf(out.data(), in, n); - } - -template -void xor_buf(std::vector& out, - const uint8_t* in, - const std::vector& in2, - size_t n) - { - xor_buf(out.data(), in, in2.data(), n); - } - -template -std::vector& -operator^=(std::vector& out, - const std::vector& in) - { - if(out.size() < in.size()) - out.resize(in.size()); - - xor_buf(out.data(), in.data(), in.size()); - return out; - } - + * Memory comparison, input insensitive + * @param x a pointer to an array + * @param y a pointer to another array + * @param len the number of Ts in x and y + * @return true iff x[i] == y[i] forall i in [0...n) + */ +inline bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len) { + return ct_compare_u8(x, y, len) == 0xFF; } +/** + * Zero out some bytes + * @param ptr a pointer to memory to zero + * @param bytes the number of bytes to zero in ptr + */ +inline void clear_bytes(void* ptr, size_t bytes) { + if (bytes > 0) { + std::memset(ptr, 0, bytes); + } +} + +/** + * Zero memory before use. This simply calls memset and should not be + * used in cases where the compiler cannot see the call as a + * side-effecting operation (for example, if calling clear_mem before + * deallocating memory, the compiler would be allowed to omit the call + * to memset entirely under the as-if rule.) + * + * @param ptr a pointer to an array of Ts to zero + * @param n the number of Ts pointed to by ptr + */ +template +inline void clear_mem(T* ptr, size_t n) { + clear_bytes(ptr, sizeof(T) * n); +} + +/** + * Copy memory + * @param out the destination array + * @param in the source array + * @param n the number of elements of in/out + */ +template +inline void copy_mem(T* out, const T* in, size_t n) { + if (n > 0) { + std::memmove(out, in, sizeof(T) * n); + } +} + +template +inline void typecast_copy(uint8_t out[], T in[], size_t N) { + std::memcpy(out, in, sizeof(T) * N); +} + +template +inline void typecast_copy(T out[], const uint8_t in[], size_t N) { + std::memcpy(out, in, sizeof(T) * N); +} + +template +inline void typecast_copy(uint8_t out[], T in) { + typecast_copy(out, &in, 1); +} + +template +inline void typecast_copy(T& out, const uint8_t in[]) { + typecast_copy(&out, in, 1); +} + +/** + * Set memory to a fixed value + * @param ptr a pointer to an array of bytes + * @param n the number of Ts pointed to by ptr + * @param val the value to set each byte to + */ +inline void set_mem(uint8_t* ptr, size_t n, uint8_t val) { + if (n > 0) { + std::memset(ptr, val, n); + } +} + +inline const uint8_t* cast_char_ptr_to_uint8(const char* s) { + return reinterpret_cast(s); +} + +inline const char* cast_uint8_ptr_to_char(const uint8_t* b) { + return reinterpret_cast(b); +} + +inline uint8_t* cast_char_ptr_to_uint8(char* s) { return reinterpret_cast(s); } + +inline char* cast_uint8_ptr_to_char(uint8_t* b) { return reinterpret_cast(b); } + +/** + * Memory comparison, input insensitive + * @param p1 a pointer to an array + * @param p2 a pointer to another array + * @param n the number of Ts in p1 and p2 + * @return true iff p1[i] == p2[i] forall i in [0...n) + */ +template +inline bool same_mem(const T* p1, const T* p2, size_t n) { + volatile T difference = 0; + + for (size_t i = 0; i != n; ++i) difference |= (p1[i] ^ p2[i]); + + return difference == 0; +} + +/** + * XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length + * @param out the input/output buffer + * @param in the read-only input buffer + * @param length the length of the buffers + */ +inline void xor_buf(uint8_t out[], const uint8_t in[], size_t length) { + const size_t blocks = length - (length % 32); + + for (size_t i = 0; i != blocks; i += 32) { + uint64_t x[4]; + uint64_t y[4]; + + typecast_copy(x, out + i, 4); + typecast_copy(y, in + i, 4); + + x[0] ^= y[0]; + x[1] ^= y[1]; + x[2] ^= y[2]; + x[3] ^= y[3]; + + typecast_copy(out + i, x, 4); + } + + for (size_t i = blocks; i != length; ++i) { + out[i] ^= in[i]; + } +} + +/** + * XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length + * @param out the output buffer + * @param in the first input buffer + * @param in2 the second output buffer + * @param length the length of the three buffers + */ +inline void xor_buf(uint8_t out[], const uint8_t in[], const uint8_t in2[], size_t length) { + const size_t blocks = length - (length % 32); + + for (size_t i = 0; i != blocks; i += 32) { + uint64_t x[4]; + uint64_t y[4]; + + typecast_copy(x, in + i, 4); + typecast_copy(y, in2 + i, 4); + + x[0] ^= y[0]; + x[1] ^= y[1]; + x[2] ^= y[2]; + x[3] ^= y[3]; + + typecast_copy(out + i, x, 4); + } + + for (size_t i = blocks; i != length; ++i) { + out[i] = in[i] ^ in2[i]; + } +} + +template +void xor_buf(std::vector& out, const std::vector& in, size_t n) { + xor_buf(out.data(), in.data(), n); +} + +template +void xor_buf(std::vector& out, const uint8_t* in, size_t n) { + xor_buf(out.data(), in, n); +} + +template +void xor_buf(std::vector& out, const uint8_t* in, + const std::vector& in2, size_t n) { + xor_buf(out.data(), in, in2.data(), n); +} + +template +std::vector& operator^=(std::vector& out, + const std::vector& in) { + if (out.size() < in.size()) out.resize(in.size()); + + xor_buf(out.data(), in.data(), in.size()); + return out; +} + +} // namespace Botan + namespace Botan { -template -class secure_allocator - { +template +class secure_allocator { public: - /* - * Assert exists to prevent someone from doing something that will - * probably crash anyway (like secure_vector where ~non_POD_t - * deletes a member pointer which was zeroed before it ran). - * MSVC in debug mode uses non-integral proxy types in container types - * like std::vector, thus we disable the check there. - */ + /* + * Assert exists to prevent someone from doing something that will + * probably crash anyway (like secure_vector where ~non_POD_t + * deletes a member pointer which was zeroed before it ran). + * MSVC in debug mode uses non-integral proxy types in container types + * like std::vector, thus we disable the check there. + */ #if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0 - static_assert(std::is_integral::value, "secure_allocator supports only integer types"); + static_assert(std::is_integral::value, "secure_allocator supports only integer types"); #endif - typedef T value_type; - typedef std::size_t size_type; + typedef T value_type; + typedef std::size_t size_type; - secure_allocator() noexcept = default; - secure_allocator(const secure_allocator&) noexcept = default; - secure_allocator& operator=(const secure_allocator&) noexcept = default; - ~secure_allocator() noexcept = default; + secure_allocator() noexcept = default; + secure_allocator(const secure_allocator&) noexcept = default; + secure_allocator& operator=(const secure_allocator&) noexcept = default; + ~secure_allocator() noexcept = default; - template - secure_allocator(const secure_allocator&) noexcept {} + template + secure_allocator(const secure_allocator&) noexcept {} - T* allocate(std::size_t n) - { - return static_cast(allocate_memory(n, sizeof(T))); - } + T* allocate(std::size_t n) { return static_cast(allocate_memory(n, sizeof(T))); } - void deallocate(T* p, std::size_t n) - { - deallocate_memory(p, n, sizeof(T)); - } - }; + void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); } +}; -template inline bool -operator==(const secure_allocator&, const secure_allocator&) - { return true; } +template +inline bool operator==(const secure_allocator&, const secure_allocator&) { + return true; +} -template inline bool -operator!=(const secure_allocator&, const secure_allocator&) - { return false; } +template +inline bool operator!=(const secure_allocator&, const secure_allocator&) { + return false; +} -template using secure_vector = std::vector>; -template using secure_deque = std::deque>; +template +using secure_vector = std::vector>; +template +using secure_deque = std::deque>; // For better compatibility with 1.10 API -template using SecureVector = secure_vector; - -template -std::vector unlock(const secure_vector& in) - { - std::vector out(in.size()); - copy_mem(out.data(), in.data(), in.size()); - return out; - } - -template -size_t buffer_insert(std::vector& buf, - size_t buf_offset, - const T input[], - size_t input_length) - { - BOTAN_ASSERT_NOMSG(buf_offset <= buf.size()); - const size_t to_copy = std::min(input_length, buf.size() - buf_offset); - if(to_copy > 0) - { - copy_mem(&buf[buf_offset], input, to_copy); - } - return to_copy; - } - -template -size_t buffer_insert(std::vector& buf, - size_t buf_offset, - const std::vector& input) - { - BOTAN_ASSERT_NOMSG(buf_offset <= buf.size()); - const size_t to_copy = std::min(input.size(), buf.size() - buf_offset); - if(to_copy > 0) - { - copy_mem(&buf[buf_offset], input.data(), to_copy); - } - return to_copy; - } - -template -std::vector& -operator+=(std::vector& out, - const std::vector& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.size()); - if(in.size() > 0) - { - copy_mem(&out[copy_offset], in.data(), in.size()); - } - return out; - } - -template -std::vector& operator+=(std::vector& out, T in) - { - out.push_back(in); - return out; - } - -template -std::vector& operator+=(std::vector& out, - const std::pair& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.second); - if(in.second > 0) - { - copy_mem(&out[copy_offset], in.first, in.second); - } - return out; - } - -template -std::vector& operator+=(std::vector& out, - const std::pair& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.second); - if(in.second > 0) - { - copy_mem(&out[copy_offset], in.first, in.second); - } - return out; - } - -/** -* Zeroise the values; length remains unchanged -* @param vec the vector to zeroise -*/ -template -void zeroise(std::vector& vec) - { - clear_mem(vec.data(), vec.size()); - } - -/** -* Zeroise the values then free the memory -* @param vec the vector to zeroise and free -*/ -template -void zap(std::vector& vec) - { - zeroise(vec); - vec.clear(); - vec.shrink_to_fit(); - } +template +using SecureVector = secure_vector; +template +std::vector unlock(const secure_vector& in) { + std::vector out(in.size()); + copy_mem(out.data(), in.data(), in.size()); + return out; } +template +size_t buffer_insert(std::vector& buf, size_t buf_offset, const T input[], + size_t input_length) { + BOTAN_ASSERT_NOMSG(buf_offset <= buf.size()); + const size_t to_copy = std::min(input_length, buf.size() - buf_offset); + if (to_copy > 0) { + copy_mem(&buf[buf_offset], input, to_copy); + } + return to_copy; +} + +template +size_t buffer_insert(std::vector& buf, size_t buf_offset, + const std::vector& input) { + BOTAN_ASSERT_NOMSG(buf_offset <= buf.size()); + const size_t to_copy = std::min(input.size(), buf.size() - buf_offset); + if (to_copy > 0) { + copy_mem(&buf[buf_offset], input.data(), to_copy); + } + return to_copy; +} + +template +std::vector& operator+=(std::vector& out, const std::vector& in) { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.size()); + if (in.size() > 0) { + copy_mem(&out[copy_offset], in.data(), in.size()); + } + return out; +} + +template +std::vector& operator+=(std::vector& out, T in) { + out.push_back(in); + return out; +} + +template +std::vector& operator+=(std::vector& out, const std::pair& in) { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.second); + if (in.second > 0) { + copy_mem(&out[copy_offset], in.first, in.second); + } + return out; +} + +template +std::vector& operator+=(std::vector& out, const std::pair& in) { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.second); + if (in.second > 0) { + copy_mem(&out[copy_offset], in.first, in.second); + } + return out; +} + +/** + * Zeroise the values; length remains unchanged + * @param vec the vector to zeroise + */ +template +void zeroise(std::vector& vec) { + clear_mem(vec.data(), vec.size()); +} + +/** + * Zeroise the values then free the memory + * @param vec the vector to zeroise and free + */ +template +void zap(std::vector& vec) { + zeroise(vec); + vec.clear(); + vec.shrink_to_fit(); +} + +} // namespace Botan + namespace Botan { /** -* Octet String -*/ -class BOTAN_PUBLIC_API(2,0) OctetString final - { + * Octet String + */ +class BOTAN_PUBLIC_API(2, 0) OctetString final { public: - /** - * @return size of this octet string in bytes - */ - size_t length() const { return m_data.size(); } - size_t size() const { return m_data.size(); } + /** + * @return size of this octet string in bytes + */ + size_t length() const { return m_data.size(); } + size_t size() const { return m_data.size(); } - /** - * @return this object as a secure_vector - */ - secure_vector bits_of() const { return m_data; } + /** + * @return this object as a secure_vector + */ + secure_vector bits_of() const { return m_data; } - /** - * @return start of this string - */ - const uint8_t* begin() const { return m_data.data(); } + /** + * @return start of this string + */ + const uint8_t* begin() const { return m_data.data(); } - /** - * @return end of this string - */ - const uint8_t* end() const { return begin() + m_data.size(); } + /** + * @return end of this string + */ + const uint8_t* end() const { return begin() + m_data.size(); } - /** - * @return this encoded as hex - */ - std::string to_string() const; + /** + * @return this encoded as hex + */ + std::string to_string() const; - std::string BOTAN_DEPRECATED("Use OctetString::to_string") as_string() const - { - return this->to_string(); - } + std::string BOTAN_DEPRECATED("Use OctetString::to_string") as_string() const { + return this->to_string(); + } - /** - * XOR the contents of another octet string into this one - * @param other octet string - * @return reference to this - */ - OctetString& operator^=(const OctetString& other); + /** + * XOR the contents of another octet string into this one + * @param other octet string + * @return reference to this + */ + OctetString& operator^=(const OctetString& other); - /** - * Force to have odd parity - */ - void set_odd_parity(); + /** + * Force to have odd parity + */ + void set_odd_parity(); - /** - * Create a new OctetString - * @param str is a hex encoded string - */ - explicit OctetString(const std::string& str = ""); + /** + * Create a new OctetString + * @param str is a hex encoded string + */ + explicit OctetString(const std::string& str = ""); - /** - * Create a new random OctetString - * @param rng is a random number generator - * @param len is the desired length in bytes - */ - OctetString(class RandomNumberGenerator& rng, size_t len); + /** + * Create a new random OctetString + * @param rng is a random number generator + * @param len is the desired length in bytes + */ + OctetString(class RandomNumberGenerator& rng, size_t len); - /** - * Create a new OctetString - * @param in is an array - * @param len is the length of in in bytes - */ - OctetString(const uint8_t in[], size_t len); + /** + * Create a new OctetString + * @param in is an array + * @param len is the length of in in bytes + */ + OctetString(const uint8_t in[], size_t len); - /** - * Create a new OctetString - * @param in a bytestring - */ - OctetString(const secure_vector& in) : m_data(in) {} + /** + * Create a new OctetString + * @param in a bytestring + */ + OctetString(const secure_vector& in) : m_data(in) {} - /** - * Create a new OctetString - * @param in a bytestring - */ - OctetString(const std::vector& in) : m_data(in.begin(), in.end()) {} + /** + * Create a new OctetString + * @param in a bytestring + */ + OctetString(const std::vector& in) : m_data(in.begin(), in.end()) {} private: - secure_vector m_data; - }; + secure_vector m_data; +}; /** -* Compare two strings -* @param x an octet string -* @param y an octet string -* @return if x is equal to y -*/ -BOTAN_PUBLIC_API(2,0) bool operator==(const OctetString& x, - const OctetString& y); + * Compare two strings + * @param x an octet string + * @param y an octet string + * @return if x is equal to y + */ +BOTAN_PUBLIC_API(2, 0) bool operator==(const OctetString& x, const OctetString& y); /** -* Compare two strings -* @param x an octet string -* @param y an octet string -* @return if x is not equal to y -*/ -BOTAN_PUBLIC_API(2,0) bool operator!=(const OctetString& x, - const OctetString& y); + * Compare two strings + * @param x an octet string + * @param y an octet string + * @return if x is not equal to y + */ +BOTAN_PUBLIC_API(2, 0) bool operator!=(const OctetString& x, const OctetString& y); /** -* Concatenate two strings -* @param x an octet string -* @param y an octet string -* @return x concatenated with y -*/ -BOTAN_PUBLIC_API(2,0) OctetString operator+(const OctetString& x, - const OctetString& y); + * Concatenate two strings + * @param x an octet string + * @param y an octet string + * @return x concatenated with y + */ +BOTAN_PUBLIC_API(2, 0) OctetString operator+(const OctetString& x, const OctetString& y); /** -* XOR two strings -* @param x an octet string -* @param y an octet string -* @return x XORed with y -*/ -BOTAN_PUBLIC_API(2,0) OctetString operator^(const OctetString& x, - const OctetString& y); - + * XOR two strings + * @param x an octet string + * @param y an octet string + * @return x XORed with y + */ +BOTAN_PUBLIC_API(2, 0) OctetString operator^(const OctetString& x, const OctetString& y); /** -* Alternate name for octet string showing intent to use as a key -*/ + * Alternate name for octet string showing intent to use as a key + */ using SymmetricKey = OctetString; /** -* Alternate name for octet string showing intent to use as an IV -*/ + * Alternate name for octet string showing intent to use as an IV + */ using InitializationVector = OctetString; -} +} // namespace Botan namespace Botan { /** -* This class represents a symmetric algorithm object. -*/ -class BOTAN_PUBLIC_API(2,0) SymmetricAlgorithm - { + * This class represents a symmetric algorithm object. + */ +class BOTAN_PUBLIC_API(2, 0) SymmetricAlgorithm { public: - virtual ~SymmetricAlgorithm() = default; + virtual ~SymmetricAlgorithm() = default; - /** - * Reset the state. - */ - virtual void clear() = 0; + /** + * Reset the state. + */ + virtual void clear() = 0; - /** - * @return object describing limits on key size - */ - virtual Key_Length_Specification key_spec() const = 0; + /** + * @return object describing limits on key size + */ + virtual Key_Length_Specification key_spec() const = 0; - /** - * @return minimum allowed key length - */ - size_t maximum_keylength() const - { - return key_spec().maximum_keylength(); - } + /** + * @return minimum allowed key length + */ + size_t maximum_keylength() const { return key_spec().maximum_keylength(); } - /** - * @return maximum allowed key length - */ - size_t minimum_keylength() const - { - return key_spec().minimum_keylength(); - } + /** + * @return maximum allowed key length + */ + size_t minimum_keylength() const { return key_spec().minimum_keylength(); } - /** - * Check whether a given key length is valid for this algorithm. - * @param length the key length to be checked. - * @return true if the key length is valid. - */ - bool valid_keylength(size_t length) const - { - return key_spec().valid_keylength(length); - } + /** + * Check whether a given key length is valid for this algorithm. + * @param length the key length to be checked. + * @return true if the key length is valid. + */ + bool valid_keylength(size_t length) const { return key_spec().valid_keylength(length); } - /** - * Set the symmetric key of this object. - * @param key the SymmetricKey to be set. - */ - void set_key(const SymmetricKey& key) - { - set_key(key.begin(), key.length()); - } + /** + * Set the symmetric key of this object. + * @param key the SymmetricKey to be set. + */ + void set_key(const SymmetricKey& key) { set_key(key.begin(), key.length()); } - template - void set_key(const std::vector& key) - { - set_key(key.data(), key.size()); - } + template + void set_key(const std::vector& key) { + set_key(key.data(), key.size()); + } - /** - * Set the symmetric key of this object. - * @param key the to be set as a byte array. - * @param length in bytes of key param - */ - void set_key(const uint8_t key[], size_t length); + /** + * Set the symmetric key of this object. + * @param key the to be set as a byte array. + * @param length in bytes of key param + */ + void set_key(const uint8_t key[], size_t length); - /** - * @return the algorithm name - */ - virtual std::string name() const = 0; + /** + * @return the algorithm name + */ + virtual std::string name() const = 0; protected: - void verify_key_set(bool cond) const - { - if(cond == false) - throw_key_not_set_error(); - } + void verify_key_set(bool cond) const { + if (cond == false) throw_key_not_set_error(); + } private: - void throw_key_not_set_error() const; + void throw_key_not_set_error() const; - /** - * Run the key schedule - * @param key the key - * @param length of key - */ - virtual void key_schedule(const uint8_t key[], size_t length) = 0; - }; + /** + * Run the key schedule + * @param key the key + * @param length of key + */ + virtual void key_schedule(const uint8_t key[], size_t length) = 0; +}; -} +} // namespace Botan namespace Botan { /** -* This class represents a block cipher object. -*/ -class BOTAN_PUBLIC_API(2,0) BlockCipher : public SymmetricAlgorithm - { + * This class represents a block cipher object. + */ +class BOTAN_PUBLIC_API(2, 0) BlockCipher : public SymmetricAlgorithm { public: + /** + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to choose + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr create(const std::string& algo_spec, + const std::string& provider = ""); - /** - * Create an instance based on a name - * If provider is empty then best available is chosen. - * @param algo_spec algorithm name - * @param provider provider implementation to choose - * @return a null pointer if the algo/provider combination cannot be found - */ - static std::unique_ptr - create(const std::string& algo_spec, - const std::string& provider = ""); + /** + * Create an instance based on a name, or throw if the + * algo/provider combination cannot be found. If provider is + * empty then best available is chosen. + */ + static std::unique_ptr create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); - /** - * Create an instance based on a name, or throw if the - * algo/provider combination cannot be found. If provider is - * empty then best available is chosen. - */ - static std::unique_ptr - create_or_throw(const std::string& algo_spec, - const std::string& provider = ""); + /** + * @return list of available providers for this algorithm, empty if not available + * @param algo_spec algorithm name + */ + static std::vector providers(const std::string& algo_spec); - /** - * @return list of available providers for this algorithm, empty if not available - * @param algo_spec algorithm name - */ - static std::vector providers(const std::string& algo_spec); + /** + * @return block size of this algorithm + */ + virtual size_t block_size() const = 0; - /** - * @return block size of this algorithm - */ - virtual size_t block_size() const = 0; + /** + * @return native parallelism of this cipher in blocks + */ + virtual size_t parallelism() const { return 1; } - /** - * @return native parallelism of this cipher in blocks - */ - virtual size_t parallelism() const { return 1; } + /** + * @return prefererred parallelism of this cipher in bytes + */ + size_t parallel_bytes() const { + return parallelism() * block_size() * BOTAN_BLOCK_CIPHER_PAR_MULT; + } - /** - * @return prefererred parallelism of this cipher in bytes - */ - size_t parallel_bytes() const - { - return parallelism() * block_size() * BOTAN_BLOCK_CIPHER_PAR_MULT; - } + /** + * @return provider information about this implementation. Default is "base", + * might also return "sse2", "avx2", "openssl", or some other arbitrary string. + */ + virtual std::string provider() const { return "base"; } - /** - * @return provider information about this implementation. Default is "base", - * might also return "sse2", "avx2", "openssl", or some other arbitrary string. - */ - virtual std::string provider() const { return "base"; } + /** + * Encrypt a block. + * @param in The plaintext block to be encrypted as a byte array. + * Must be of length block_size(). + * @param out The byte array designated to hold the encrypted block. + * Must be of length block_size(). + */ + void encrypt(const uint8_t in[], uint8_t out[]) const { encrypt_n(in, out, 1); } - /** - * Encrypt a block. - * @param in The plaintext block to be encrypted as a byte array. - * Must be of length block_size(). - * @param out The byte array designated to hold the encrypted block. - * Must be of length block_size(). - */ - void encrypt(const uint8_t in[], uint8_t out[]) const - { encrypt_n(in, out, 1); } + /** + * Decrypt a block. + * @param in The ciphertext block to be decypted as a byte array. + * Must be of length block_size(). + * @param out The byte array designated to hold the decrypted block. + * Must be of length block_size(). + */ + void decrypt(const uint8_t in[], uint8_t out[]) const { decrypt_n(in, out, 1); } - /** - * Decrypt a block. - * @param in The ciphertext block to be decypted as a byte array. - * Must be of length block_size(). - * @param out The byte array designated to hold the decrypted block. - * Must be of length block_size(). - */ - void decrypt(const uint8_t in[], uint8_t out[]) const - { decrypt_n(in, out, 1); } + /** + * Encrypt a block. + * @param block the plaintext block to be encrypted + * Must be of length block_size(). Will hold the result when the function + * has finished. + */ + void encrypt(uint8_t block[]) const { encrypt_n(block, block, 1); } - /** - * Encrypt a block. - * @param block the plaintext block to be encrypted - * Must be of length block_size(). Will hold the result when the function - * has finished. - */ - void encrypt(uint8_t block[]) const { encrypt_n(block, block, 1); } + /** + * Decrypt a block. + * @param block the ciphertext block to be decrypted + * Must be of length block_size(). Will hold the result when the function + * has finished. + */ + void decrypt(uint8_t block[]) const { decrypt_n(block, block, 1); } - /** - * Decrypt a block. - * @param block the ciphertext block to be decrypted - * Must be of length block_size(). Will hold the result when the function - * has finished. - */ - void decrypt(uint8_t block[]) const { decrypt_n(block, block, 1); } + /** + * Encrypt one or more blocks + * @param block the input/output buffer (multiple of block_size()) + */ + template + void encrypt(std::vector& block) const { + return encrypt_n(block.data(), block.data(), block.size() / block_size()); + } - /** - * Encrypt one or more blocks - * @param block the input/output buffer (multiple of block_size()) - */ - template - void encrypt(std::vector& block) const - { - return encrypt_n(block.data(), block.data(), block.size() / block_size()); - } + /** + * Decrypt one or more blocks + * @param block the input/output buffer (multiple of block_size()) + */ + template + void decrypt(std::vector& block) const { + return decrypt_n(block.data(), block.data(), block.size() / block_size()); + } - /** - * Decrypt one or more blocks - * @param block the input/output buffer (multiple of block_size()) - */ - template - void decrypt(std::vector& block) const - { - return decrypt_n(block.data(), block.data(), block.size() / block_size()); - } + /** + * Encrypt one or more blocks + * @param in the input buffer (multiple of block_size()) + * @param out the output buffer (same size as in) + */ + template + void encrypt(const std::vector& in, std::vector& out) const { + return encrypt_n(in.data(), out.data(), in.size() / block_size()); + } - /** - * Encrypt one or more blocks - * @param in the input buffer (multiple of block_size()) - * @param out the output buffer (same size as in) - */ - template - void encrypt(const std::vector& in, - std::vector& out) const - { - return encrypt_n(in.data(), out.data(), in.size() / block_size()); - } + /** + * Decrypt one or more blocks + * @param in the input buffer (multiple of block_size()) + * @param out the output buffer (same size as in) + */ + template + void decrypt(const std::vector& in, std::vector& out) const { + return decrypt_n(in.data(), out.data(), in.size() / block_size()); + } - /** - * Decrypt one or more blocks - * @param in the input buffer (multiple of block_size()) - * @param out the output buffer (same size as in) - */ - template - void decrypt(const std::vector& in, - std::vector& out) const - { - return decrypt_n(in.data(), out.data(), in.size() / block_size()); - } + /** + * Encrypt one or more blocks + * @param in the input buffer (multiple of block_size()) + * @param out the output buffer (same size as in) + * @param blocks the number of blocks to process + */ + virtual void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const = 0; - /** - * Encrypt one or more blocks - * @param in the input buffer (multiple of block_size()) - * @param out the output buffer (same size as in) - * @param blocks the number of blocks to process - */ - virtual void encrypt_n(const uint8_t in[], uint8_t out[], - size_t blocks) const = 0; + /** + * Decrypt one or more blocks + * @param in the input buffer (multiple of block_size()) + * @param out the output buffer (same size as in) + * @param blocks the number of blocks to process + */ + virtual void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const = 0; - /** - * Decrypt one or more blocks - * @param in the input buffer (multiple of block_size()) - * @param out the output buffer (same size as in) - * @param blocks the number of blocks to process - */ - virtual void decrypt_n(const uint8_t in[], uint8_t out[], - size_t blocks) const = 0; + virtual void encrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const { + const size_t BS = block_size(); + xor_buf(data, mask, blocks * BS); + encrypt_n(data, data, blocks); + xor_buf(data, mask, blocks * BS); + } - virtual void encrypt_n_xex(uint8_t data[], - const uint8_t mask[], - size_t blocks) const - { - const size_t BS = block_size(); - xor_buf(data, mask, blocks * BS); - encrypt_n(data, data, blocks); - xor_buf(data, mask, blocks * BS); - } + virtual void decrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const { + const size_t BS = block_size(); + xor_buf(data, mask, blocks * BS); + decrypt_n(data, data, blocks); + xor_buf(data, mask, blocks * BS); + } - virtual void decrypt_n_xex(uint8_t data[], - const uint8_t mask[], - size_t blocks) const - { - const size_t BS = block_size(); - xor_buf(data, mask, blocks * BS); - decrypt_n(data, data, blocks); - xor_buf(data, mask, blocks * BS); - } + /** + * @return new object representing the same algorithm as *this + */ + virtual BlockCipher* clone() const = 0; - /** - * @return new object representing the same algorithm as *this - */ - virtual BlockCipher* clone() const = 0; - - virtual ~BlockCipher() = default; - }; + virtual ~BlockCipher() = default; +}; /** -* Tweakable block ciphers allow setting a tweak which is a non-keyed -* value which affects the encryption/decryption operation. -*/ -class BOTAN_PUBLIC_API(2,8) Tweakable_Block_Cipher : public BlockCipher - { + * Tweakable block ciphers allow setting a tweak which is a non-keyed + * value which affects the encryption/decryption operation. + */ +class BOTAN_PUBLIC_API(2, 8) Tweakable_Block_Cipher : public BlockCipher { public: - /** - * Set the tweak value. This must be called after setting a key. The value - * persists until either set_tweak, set_key, or clear is called. - * Different algorithms support different tweak length(s). If called with - * an unsupported length, Invalid_Argument will be thrown. - */ - virtual void set_tweak(const uint8_t tweak[], size_t len) = 0; - }; + /** + * Set the tweak value. This must be called after setting a key. The value + * persists until either set_tweak, set_key, or clear is called. + * Different algorithms support different tweak length(s). If called with + * an unsupported length, Invalid_Argument will be thrown. + */ + virtual void set_tweak(const uint8_t tweak[], size_t len) = 0; +}; /** -* Represents a block cipher with a single fixed block size -*/ -template -class Block_Cipher_Fixed_Params : public BaseClass - { + * Represents a block cipher with a single fixed block size + */ +template +class Block_Cipher_Fixed_Params : public BaseClass { public: - enum { BLOCK_SIZE = BS }; - size_t block_size() const final override { return BS; } + enum { BLOCK_SIZE = BS }; + size_t block_size() const final override { return BS; } - // override to take advantage of compile time constant block size - void encrypt_n_xex(uint8_t data[], - const uint8_t mask[], - size_t blocks) const final override - { - xor_buf(data, mask, blocks * BS); - this->encrypt_n(data, data, blocks); - xor_buf(data, mask, blocks * BS); - } + // override to take advantage of compile time constant block size + void encrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const final override { + xor_buf(data, mask, blocks * BS); + this->encrypt_n(data, data, blocks); + xor_buf(data, mask, blocks * BS); + } - void decrypt_n_xex(uint8_t data[], - const uint8_t mask[], - size_t blocks) const final override - { - xor_buf(data, mask, blocks * BS); - this->decrypt_n(data, data, blocks); - xor_buf(data, mask, blocks * BS); - } + void decrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const final override { + xor_buf(data, mask, blocks * BS); + this->decrypt_n(data, data, blocks); + xor_buf(data, mask, blocks * BS); + } - Key_Length_Specification key_spec() const final override - { - return Key_Length_Specification(KMIN, KMAX, KMOD); - } - }; + Key_Length_Specification key_spec() const final override { + return Key_Length_Specification(KMIN, KMAX, KMOD); + } +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(aes.h) +// BOTAN_FUTURE_INTERNAL_HEADER(aes.h) namespace Botan { /** -* AES-128 -*/ -class BOTAN_PUBLIC_API(2,0) AES_128 final : public Block_Cipher_Fixed_Params<16, 16> - { + * AES-128 + */ +class BOTAN_PUBLIC_API(2, 0) AES_128 final : public Block_Cipher_Fixed_Params<16, 16> { public: - void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; - void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; - void clear() override; + void clear() override; - std::string provider() const override; - std::string name() const override { return "AES-128"; } - BlockCipher* clone() const override { return new AES_128; } - size_t parallelism() const override; + std::string provider() const override; + std::string name() const override { return "AES-128"; } + BlockCipher* clone() const override { return new AES_128; } + size_t parallelism() const override; private: - void key_schedule(const uint8_t key[], size_t length) override; + void key_schedule(const uint8_t key[], size_t length) override; #if defined(BOTAN_HAS_AES_VPERM) - void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void vperm_key_schedule(const uint8_t key[], size_t length); + void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void vperm_key_schedule(const uint8_t key[], size_t length); #endif #if defined(BOTAN_HAS_AES_NI) - void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void aesni_key_schedule(const uint8_t key[], size_t length); + void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_key_schedule(const uint8_t key[], size_t length); #endif #if defined(BOTAN_HAS_AES_ARMV8) - void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; #endif #if defined(BOTAN_HAS_AES_POWER8) - void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; #endif - secure_vector m_EK, m_DK; - secure_vector m_ME, m_MD; - }; + secure_vector m_EK, m_DK; + secure_vector m_ME, m_MD; +}; /** -* AES-192 -*/ -class BOTAN_PUBLIC_API(2,0) AES_192 final : public Block_Cipher_Fixed_Params<16, 24> - { + * AES-192 + */ +class BOTAN_PUBLIC_API(2, 0) AES_192 final : public Block_Cipher_Fixed_Params<16, 24> { public: - void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; - void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; - void clear() override; + void clear() override; - std::string provider() const override; - std::string name() const override { return "AES-192"; } - BlockCipher* clone() const override { return new AES_192; } - size_t parallelism() const override; + std::string provider() const override; + std::string name() const override { return "AES-192"; } + BlockCipher* clone() const override { return new AES_192; } + size_t parallelism() const override; private: #if defined(BOTAN_HAS_AES_VPERM) - void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void vperm_key_schedule(const uint8_t key[], size_t length); + void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void vperm_key_schedule(const uint8_t key[], size_t length); #endif #if defined(BOTAN_HAS_AES_NI) - void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void aesni_key_schedule(const uint8_t key[], size_t length); + void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_key_schedule(const uint8_t key[], size_t length); #endif #if defined(BOTAN_HAS_AES_ARMV8) - void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; #endif #if defined(BOTAN_HAS_AES_POWER8) - void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; #endif - void key_schedule(const uint8_t key[], size_t length) override; + void key_schedule(const uint8_t key[], size_t length) override; - secure_vector m_EK, m_DK; - secure_vector m_ME, m_MD; - }; + secure_vector m_EK, m_DK; + secure_vector m_ME, m_MD; +}; /** -* AES-256 -*/ -class BOTAN_PUBLIC_API(2,0) AES_256 final : public Block_Cipher_Fixed_Params<16, 32> - { + * AES-256 + */ +class BOTAN_PUBLIC_API(2, 0) AES_256 final : public Block_Cipher_Fixed_Params<16, 32> { public: - void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; - void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; - void clear() override; + void clear() override; - std::string provider() const override; + std::string provider() const override; - std::string name() const override { return "AES-256"; } - BlockCipher* clone() const override { return new AES_256; } - size_t parallelism() const override; + std::string name() const override { return "AES-256"; } + BlockCipher* clone() const override { return new AES_256; } + size_t parallelism() const override; private: #if defined(BOTAN_HAS_AES_VPERM) - void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void vperm_key_schedule(const uint8_t key[], size_t length); + void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void vperm_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void vperm_key_schedule(const uint8_t key[], size_t length); #endif #if defined(BOTAN_HAS_AES_NI) - void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void aesni_key_schedule(const uint8_t key[], size_t length); + void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_key_schedule(const uint8_t key[], size_t length); #endif #if defined(BOTAN_HAS_AES_ARMV8) - void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; #endif #if defined(BOTAN_HAS_AES_POWER8) - void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; - void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; #endif - void key_schedule(const uint8_t key[], size_t length) override; + void key_schedule(const uint8_t key[], size_t length) override; - secure_vector m_EK, m_DK; - secure_vector m_ME, m_MD; - }; + secure_vector m_EK, m_DK; + secure_vector m_ME, m_MD; +}; -} +} // namespace Botan namespace Botan { /** -* Different types of errors that might occur -*/ + * Different types of errors that might occur + */ enum class ErrorType { - /** Some unknown error */ - Unknown = 1, - /** An error while calling a system interface */ - SystemError, - /** An operation seems valid, but not supported by the current version */ - NotImplemented, - /** Memory allocation failure */ - OutOfMemory, - /** An internal error occurred */ - InternalError, - /** An I/O error occurred */ - IoError, + /** Some unknown error */ + Unknown = 1, + /** An error while calling a system interface */ + SystemError, + /** An operation seems valid, but not supported by the current version */ + NotImplemented, + /** Memory allocation failure */ + OutOfMemory, + /** An internal error occurred */ + InternalError, + /** An I/O error occurred */ + IoError, - /** Invalid object state */ - InvalidObjectState = 100, - /** A key was not set on an object when this is required */ - KeyNotSet, - /** The application provided an argument which is invalid */ - InvalidArgument, - /** A key with invalid length was provided */ - InvalidKeyLength, - /** A nonce with invalid length was provided */ - InvalidNonceLength, - /** An object type was requested but cannot be found */ - LookupError, - /** Encoding a message or datum failed */ - EncodingFailure, - /** Decoding a message or datum failed */ - DecodingFailure, - /** A TLS error (error_code will be the alert type) */ - TLSError, - /** An error during an HTTP operation */ - HttpError, - /** A message with an invalid authentication tag was detected */ - InvalidTag, + /** Invalid object state */ + InvalidObjectState = 100, + /** A key was not set on an object when this is required */ + KeyNotSet, + /** The application provided an argument which is invalid */ + InvalidArgument, + /** A key with invalid length was provided */ + InvalidKeyLength, + /** A nonce with invalid length was provided */ + InvalidNonceLength, + /** An object type was requested but cannot be found */ + LookupError, + /** Encoding a message or datum failed */ + EncodingFailure, + /** Decoding a message or datum failed */ + DecodingFailure, + /** A TLS error (error_code will be the alert type) */ + TLSError, + /** An error during an HTTP operation */ + HttpError, + /** A message with an invalid authentication tag was detected */ + InvalidTag, - /** An error when calling OpenSSL */ - OpenSSLError = 200, - /** An error when interacting with CommonCrypto API */ - CommonCryptoError, - /** An error when interacting with a PKCS11 device */ - Pkcs11Error, - /** An error when interacting with a TPM device */ - TPMError, - /** An error when interacting with a database */ - DatabaseError, + /** An error when calling OpenSSL */ + OpenSSLError = 200, + /** An error when interacting with CommonCrypto API */ + CommonCryptoError, + /** An error when interacting with a PKCS11 device */ + Pkcs11Error, + /** An error when interacting with a TPM device */ + TPMError, + /** An error when interacting with a database */ + DatabaseError, - /** An error when interacting with zlib */ - ZlibError = 300, - /** An error when interacting with bzip2 */ - Bzip2Error, - /** An error when interacting with lzma */ - LzmaError, + /** An error when interacting with zlib */ + ZlibError = 300, + /** An error when interacting with bzip2 */ + Bzip2Error, + /** An error when interacting with lzma */ + LzmaError, }; //! \brief Convert an ErrorType to string -std::string BOTAN_PUBLIC_API(2,11) to_string(ErrorType type); +std::string BOTAN_PUBLIC_API(2, 11) to_string(ErrorType type); /** -* Base class for all exceptions thrown by the library -*/ -class BOTAN_PUBLIC_API(2,0) Exception : public std::exception - { + * Base class for all exceptions thrown by the library + */ +class BOTAN_PUBLIC_API(2, 0) Exception : public std::exception { public: - /** - * Return a descriptive string which is hopefully comprehensible to - * a developer. It will likely not be useful for an end user. - * - * The string has no particular format, and the content of exception - * messages may change from release to release. Thus the main use of this - * function is for logging or debugging. - */ - const char* what() const noexcept override { return m_msg.c_str(); } + /** + * Return a descriptive string which is hopefully comprehensible to + * a developer. It will likely not be useful for an end user. + * + * The string has no particular format, and the content of exception + * messages may change from release to release. Thus the main use of this + * function is for logging or debugging. + */ + const char* what() const noexcept override { return m_msg.c_str(); } - /** - * Return the "type" of error which occurred. - */ - virtual ErrorType error_type() const noexcept { return Botan::ErrorType::Unknown; } + /** + * Return the "type" of error which occurred. + */ + virtual ErrorType error_type() const noexcept { return Botan::ErrorType::Unknown; } - /** - * Return an error code associated with this exception, or otherwise 0. - * - * The domain of this error varies depending on the source, for example on - * POSIX systems it might be errno, while on a Windows system it might be - * the result of GetLastError or WSAGetLastError. For error_type() is - * OpenSSLError, it will (if nonzero) be an OpenSSL error code from - * ERR_get_error. - */ - virtual int error_code() const noexcept { return 0; } + /** + * Return an error code associated with this exception, or otherwise 0. + * + * The domain of this error varies depending on the source, for example on + * POSIX systems it might be errno, while on a Windows system it might be + * the result of GetLastError or WSAGetLastError. For error_type() is + * OpenSSLError, it will (if nonzero) be an OpenSSL error code from + * ERR_get_error. + */ + virtual int error_code() const noexcept { return 0; } - /** - * Avoid throwing base Exception, use a subclass - */ - explicit Exception(const std::string& msg); + /** + * Avoid throwing base Exception, use a subclass + */ + explicit Exception(const std::string& msg); - /** - * Avoid throwing base Exception, use a subclass - */ - Exception(const char* prefix, const std::string& msg); + /** + * Avoid throwing base Exception, use a subclass + */ + Exception(const char* prefix, const std::string& msg); - /** - * Avoid throwing base Exception, use a subclass - */ - Exception(const std::string& msg, const std::exception& e); + /** + * Avoid throwing base Exception, use a subclass + */ + Exception(const std::string& msg, const std::exception& e); private: - std::string m_msg; - }; + std::string m_msg; +}; /** -* An invalid argument was provided to an API call. -*/ -class BOTAN_PUBLIC_API(2,0) Invalid_Argument : public Exception - { + * An invalid argument was provided to an API call. + */ +class BOTAN_PUBLIC_API(2, 0) Invalid_Argument : public Exception { public: - explicit Invalid_Argument(const std::string& msg); + explicit Invalid_Argument(const std::string& msg); - explicit Invalid_Argument(const std::string& msg, const std::string& where); + explicit Invalid_Argument(const std::string& msg, const std::string& where); - Invalid_Argument(const std::string& msg, const std::exception& e); + Invalid_Argument(const std::string& msg, const std::exception& e); - ErrorType error_type() const noexcept override { return ErrorType::InvalidArgument; } - }; + ErrorType error_type() const noexcept override { return ErrorType::InvalidArgument; } +}; /** -* An invalid key length was used -*/ -class BOTAN_PUBLIC_API(2,0) Invalid_Key_Length final : public Invalid_Argument - { + * An invalid key length was used + */ +class BOTAN_PUBLIC_API(2, 0) Invalid_Key_Length final : public Invalid_Argument { public: - Invalid_Key_Length(const std::string& name, size_t length); - ErrorType error_type() const noexcept override { return ErrorType::InvalidKeyLength; } - }; + Invalid_Key_Length(const std::string& name, size_t length); + ErrorType error_type() const noexcept override { return ErrorType::InvalidKeyLength; } +}; /** -* An invalid nonce length was used -*/ -class BOTAN_PUBLIC_API(2,0) Invalid_IV_Length final : public Invalid_Argument - { + * An invalid nonce length was used + */ +class BOTAN_PUBLIC_API(2, 0) Invalid_IV_Length final : public Invalid_Argument { public: - Invalid_IV_Length(const std::string& mode, size_t bad_len); - ErrorType error_type() const noexcept override { return ErrorType::InvalidNonceLength; } - }; + Invalid_IV_Length(const std::string& mode, size_t bad_len); + ErrorType error_type() const noexcept override { return ErrorType::InvalidNonceLength; } +}; /** -* Invalid_Algorithm_Name Exception -*/ -class BOTAN_PUBLIC_API(2,0) Invalid_Algorithm_Name final : public Invalid_Argument - { + * Invalid_Algorithm_Name Exception + */ +class BOTAN_PUBLIC_API(2, 0) Invalid_Algorithm_Name final : public Invalid_Argument { public: - explicit Invalid_Algorithm_Name(const std::string& name); - }; + explicit Invalid_Algorithm_Name(const std::string& name); +}; /** -* Encoding_Error Exception -* -* This exception derives from Invalid_Argument for historical reasons, and it -* does not make any real sense for it to do so. In a future major release this -* exception type will derive directly from Exception instead. -*/ -class BOTAN_PUBLIC_API(2,0) Encoding_Error final : public Invalid_Argument - { + * Encoding_Error Exception + * + * This exception derives from Invalid_Argument for historical reasons, and it + * does not make any real sense for it to do so. In a future major release this + * exception type will derive directly from Exception instead. + */ +class BOTAN_PUBLIC_API(2, 0) Encoding_Error final : public Invalid_Argument { public: - explicit Encoding_Error(const std::string& name); + explicit Encoding_Error(const std::string& name); - ErrorType error_type() const noexcept override { return ErrorType::EncodingFailure; } - }; + ErrorType error_type() const noexcept override { return ErrorType::EncodingFailure; } +}; /** -* A decoding error occurred. -* -* This exception derives from Invalid_Argument for historical reasons, and it -* does not make any real sense for it to do so. In a future major release this -* exception type will derive directly from Exception instead. -*/ -class BOTAN_PUBLIC_API(2,0) Decoding_Error : public Invalid_Argument - { + * A decoding error occurred. + * + * This exception derives from Invalid_Argument for historical reasons, and it + * does not make any real sense for it to do so. In a future major release this + * exception type will derive directly from Exception instead. + */ +class BOTAN_PUBLIC_API(2, 0) Decoding_Error : public Invalid_Argument { public: - explicit Decoding_Error(const std::string& name); + explicit Decoding_Error(const std::string& name); - Decoding_Error(const std::string& name, const char* exception_message); + Decoding_Error(const std::string& name, const char* exception_message); - Decoding_Error(const std::string& msg, const std::exception& e); + Decoding_Error(const std::string& msg, const std::exception& e); - ErrorType error_type() const noexcept override { return ErrorType::DecodingFailure; } - }; + ErrorType error_type() const noexcept override { return ErrorType::DecodingFailure; } +}; /** -* Invalid state was encountered. A request was made on an object while the -* object was in a state where the operation cannot be performed. -*/ -class BOTAN_PUBLIC_API(2,0) Invalid_State : public Exception - { + * Invalid state was encountered. A request was made on an object while the + * object was in a state where the operation cannot be performed. + */ +class BOTAN_PUBLIC_API(2, 0) Invalid_State : public Exception { public: - explicit Invalid_State(const std::string& err) : Exception(err) {} + explicit Invalid_State(const std::string& err) : Exception(err) {} - ErrorType error_type() const noexcept override { return ErrorType::InvalidObjectState; } - }; + ErrorType error_type() const noexcept override { return ErrorType::InvalidObjectState; } +}; /** -* A PRNG was called on to produce output while still unseeded -*/ -class BOTAN_PUBLIC_API(2,0) PRNG_Unseeded final : public Invalid_State - { + * A PRNG was called on to produce output while still unseeded + */ +class BOTAN_PUBLIC_API(2, 0) PRNG_Unseeded final : public Invalid_State { public: - explicit PRNG_Unseeded(const std::string& algo); - }; + explicit PRNG_Unseeded(const std::string& algo); +}; /** -* The key was not set on an object. This occurs with symmetric objects where -* an operation which requires the key is called prior to set_key being called. -*/ -class BOTAN_PUBLIC_API(2,4) Key_Not_Set : public Invalid_State - { + * The key was not set on an object. This occurs with symmetric objects where + * an operation which requires the key is called prior to set_key being called. + */ +class BOTAN_PUBLIC_API(2, 4) Key_Not_Set : public Invalid_State { public: - explicit Key_Not_Set(const std::string& algo); + explicit Key_Not_Set(const std::string& algo); - ErrorType error_type() const noexcept override { return ErrorType::KeyNotSet; } - }; + ErrorType error_type() const noexcept override { return ErrorType::KeyNotSet; } +}; /** -* A request was made for some kind of object which could not be located -*/ -class BOTAN_PUBLIC_API(2,0) Lookup_Error : public Exception - { + * A request was made for some kind of object which could not be located + */ +class BOTAN_PUBLIC_API(2, 0) Lookup_Error : public Exception { public: - explicit Lookup_Error(const std::string& err) : Exception(err) {} + explicit Lookup_Error(const std::string& err) : Exception(err) {} - Lookup_Error(const std::string& type, - const std::string& algo, - const std::string& provider); + Lookup_Error(const std::string& type, const std::string& algo, const std::string& provider); - ErrorType error_type() const noexcept override { return ErrorType::LookupError; } - }; + ErrorType error_type() const noexcept override { return ErrorType::LookupError; } +}; /** -* Algorithm_Not_Found Exception -* -* @warning This exception type will be removed in the future. Instead -* just catch Lookup_Error. -*/ -class BOTAN_PUBLIC_API(2,0) Algorithm_Not_Found final : public Lookup_Error - { + * Algorithm_Not_Found Exception + * + * @warning This exception type will be removed in the future. Instead + * just catch Lookup_Error. + */ +class BOTAN_PUBLIC_API(2, 0) Algorithm_Not_Found final : public Lookup_Error { public: - explicit Algorithm_Not_Found(const std::string& name); - }; + explicit Algorithm_Not_Found(const std::string& name); +}; /** -* Provider_Not_Found is thrown when a specific provider was requested -* but that provider is not available. -* -* @warning This exception type will be removed in the future. Instead -* just catch Lookup_Error. -*/ -class BOTAN_PUBLIC_API(2,0) Provider_Not_Found final : public Lookup_Error - { + * Provider_Not_Found is thrown when a specific provider was requested + * but that provider is not available. + * + * @warning This exception type will be removed in the future. Instead + * just catch Lookup_Error. + */ +class BOTAN_PUBLIC_API(2, 0) Provider_Not_Found final : public Lookup_Error { public: - Provider_Not_Found(const std::string& algo, const std::string& provider); - }; + Provider_Not_Found(const std::string& algo, const std::string& provider); +}; /** -* An AEAD or MAC check detected a message modification -* -* In versions before 2.10, Invalid_Authentication_Tag was named -* Integrity_Failure, it was renamed to make its usage more clear. -*/ -class BOTAN_PUBLIC_API(2,0) Invalid_Authentication_Tag final : public Exception - { + * An AEAD or MAC check detected a message modification + * + * In versions before 2.10, Invalid_Authentication_Tag was named + * Integrity_Failure, it was renamed to make its usage more clear. + */ +class BOTAN_PUBLIC_API(2, 0) Invalid_Authentication_Tag final : public Exception { public: - explicit Invalid_Authentication_Tag(const std::string& msg); + explicit Invalid_Authentication_Tag(const std::string& msg); - ErrorType error_type() const noexcept override { return ErrorType::InvalidTag; } - }; + ErrorType error_type() const noexcept override { return ErrorType::InvalidTag; } +}; /** -* For compatability with older versions -*/ + * For compatability with older versions + */ typedef Invalid_Authentication_Tag Integrity_Failure; /** -* An error occurred while operating on an IO stream -*/ -class BOTAN_PUBLIC_API(2,0) Stream_IO_Error final : public Exception - { + * An error occurred while operating on an IO stream + */ +class BOTAN_PUBLIC_API(2, 0) Stream_IO_Error final : public Exception { public: - explicit Stream_IO_Error(const std::string& err); + explicit Stream_IO_Error(const std::string& err); - ErrorType error_type() const noexcept override { return ErrorType::IoError; } - }; + ErrorType error_type() const noexcept override { return ErrorType::IoError; } +}; /** -* System_Error -* -* This exception is thrown in the event of an error related to interacting -* with the operating system. -* -* This exception type also (optionally) captures an integer error code eg -* POSIX errno or Windows GetLastError. -*/ -class BOTAN_PUBLIC_API(2,9) System_Error : public Exception - { + * System_Error + * + * This exception is thrown in the event of an error related to interacting + * with the operating system. + * + * This exception type also (optionally) captures an integer error code eg + * POSIX errno or Windows GetLastError. + */ +class BOTAN_PUBLIC_API(2, 9) System_Error : public Exception { public: - System_Error(const std::string& msg) : Exception(msg), m_error_code(0) {} + System_Error(const std::string& msg) : Exception(msg), m_error_code(0) {} - System_Error(const std::string& msg, int err_code); + System_Error(const std::string& msg, int err_code); - ErrorType error_type() const noexcept override { return ErrorType::SystemError; } + ErrorType error_type() const noexcept override { return ErrorType::SystemError; } - int error_code() const noexcept override { return m_error_code; } + int error_code() const noexcept override { return m_error_code; } private: - int m_error_code; - }; + int m_error_code; +}; /** -* An internal error occurred. If observed, please file a bug. -*/ -class BOTAN_PUBLIC_API(2,0) Internal_Error : public Exception - { + * An internal error occurred. If observed, please file a bug. + */ +class BOTAN_PUBLIC_API(2, 0) Internal_Error : public Exception { public: - explicit Internal_Error(const std::string& err); + explicit Internal_Error(const std::string& err); - ErrorType error_type() const noexcept override { return ErrorType::InternalError; } - }; + ErrorType error_type() const noexcept override { return ErrorType::InternalError; } +}; /** -* Not Implemented Exception -* -* This is thrown in the situation where a requested operation is -* logically valid but is not implemented by this version of the library. -*/ -class BOTAN_PUBLIC_API(2,0) Not_Implemented final : public Exception - { + * Not Implemented Exception + * + * This is thrown in the situation where a requested operation is + * logically valid but is not implemented by this version of the library. + */ +class BOTAN_PUBLIC_API(2, 0) Not_Implemented final : public Exception { public: - explicit Not_Implemented(const std::string& err); + explicit Not_Implemented(const std::string& err); - ErrorType error_type() const noexcept override { return ErrorType::NotImplemented; } - }; + ErrorType error_type() const noexcept override { return ErrorType::NotImplemented; } +}; /* The following exception types are still in use for compatability reasons, @@ -2246,15 +2071,14 @@ class BOTAN_PUBLIC_API(2,0) Not_Implemented final : public Exception */ /** -* An invalid OID string was used. -* -* This exception will be removed in a future major release. -*/ -class BOTAN_PUBLIC_API(2,0) Invalid_OID final : public Decoding_Error - { + * An invalid OID string was used. + * + * This exception will be removed in a future major release. + */ +class BOTAN_PUBLIC_API(2, 0) Invalid_OID final : public Decoding_Error { public: - explicit Invalid_OID(const std::string& oid); - }; + explicit Invalid_OID(const std::string& oid); +}; /* The following exception types are deprecated, no longer used, @@ -2262,200 +2086,193 @@ class BOTAN_PUBLIC_API(2,0) Invalid_OID final : public Decoding_Error */ /** -* Self Test Failure Exception -* -* This exception is no longer used. It will be removed in a future major release. -*/ -class BOTAN_PUBLIC_API(2,0) Self_Test_Failure final : public Internal_Error - { + * Self Test Failure Exception + * + * This exception is no longer used. It will be removed in a future major release. + */ +class BOTAN_PUBLIC_API(2, 0) Self_Test_Failure final : public Internal_Error { public: - BOTAN_DEPRECATED("no longer used") explicit Self_Test_Failure(const std::string& err); - }; + BOTAN_DEPRECATED("no longer used") explicit Self_Test_Failure(const std::string& err); +}; /** -* No_Provider_Found Exception -* -* This exception is no longer used. It will be removed in a future major release. -*/ -class BOTAN_PUBLIC_API(2,0) No_Provider_Found final : public Exception - { + * No_Provider_Found Exception + * + * This exception is no longer used. It will be removed in a future major release. + */ +class BOTAN_PUBLIC_API(2, 0) No_Provider_Found final : public Exception { public: - BOTAN_DEPRECATED("no longer used") explicit No_Provider_Found(const std::string& name); - }; + BOTAN_DEPRECATED("no longer used") explicit No_Provider_Found(const std::string& name); +}; /** -* Policy_Violation Exception -* -* This exception is no longer used. It will be removed in a future major release. -*/ -class BOTAN_PUBLIC_API(2,0) Policy_Violation final : public Invalid_State - { + * Policy_Violation Exception + * + * This exception is no longer used. It will be removed in a future major release. + */ +class BOTAN_PUBLIC_API(2, 0) Policy_Violation final : public Invalid_State { public: - BOTAN_DEPRECATED("no longer used") explicit Policy_Violation(const std::string& err); - }; + BOTAN_DEPRECATED("no longer used") explicit Policy_Violation(const std::string& err); +}; /** -* Unsupported_Argument Exception -* -* An argument that is invalid because it is not supported by Botan. -* It might or might not be valid in another context like a standard. -* -* This exception is no longer used, instead Not_Implemented is thrown. -* It will be removed in a future major release. -*/ -class BOTAN_PUBLIC_API(2,0) Unsupported_Argument final : public Invalid_Argument - { + * Unsupported_Argument Exception + * + * An argument that is invalid because it is not supported by Botan. + * It might or might not be valid in another context like a standard. + * + * This exception is no longer used, instead Not_Implemented is thrown. + * It will be removed in a future major release. + */ +class BOTAN_PUBLIC_API(2, 0) Unsupported_Argument final : public Invalid_Argument { public: - BOTAN_DEPRECATED("no longer used") explicit Unsupported_Argument(const std::string& msg) : Invalid_Argument(msg) {} - }; - -template -inline void do_throw_error(const char* file, int line, const char* func, Args... args) - { - throw E(file, line, func, args...); - } + BOTAN_DEPRECATED("no longer used") + explicit Unsupported_Argument(const std::string& msg) : Invalid_Argument(msg) {} +}; +template +inline void do_throw_error(const char* file, int line, const char* func, Args... args) { + throw E(file, line, func, args...); } +} // namespace Botan + namespace Botan { class BER_Decoder; class DER_Encoder; /** -* ASN.1 Type and Class Tags -* This will become an enum class in a future major release -*/ + * ASN.1 Type and Class Tags + * This will become an enum class in a future major release + */ enum ASN1_Tag : uint32_t { - UNIVERSAL = 0x00, - APPLICATION = 0x40, - CONTEXT_SPECIFIC = 0x80, + UNIVERSAL = 0x00, + APPLICATION = 0x40, + CONTEXT_SPECIFIC = 0x80, - CONSTRUCTED = 0x20, + CONSTRUCTED = 0x20, - PRIVATE = CONSTRUCTED | CONTEXT_SPECIFIC, + PRIVATE = CONSTRUCTED | CONTEXT_SPECIFIC, - EOC = 0x00, - BOOLEAN = 0x01, - INTEGER = 0x02, - BIT_STRING = 0x03, - OCTET_STRING = 0x04, - NULL_TAG = 0x05, - OBJECT_ID = 0x06, - ENUMERATED = 0x0A, - SEQUENCE = 0x10, - SET = 0x11, + EOC = 0x00, + BOOLEAN = 0x01, + INTEGER = 0x02, + BIT_STRING = 0x03, + OCTET_STRING = 0x04, + NULL_TAG = 0x05, + OBJECT_ID = 0x06, + ENUMERATED = 0x0A, + SEQUENCE = 0x10, + SET = 0x11, - UTF8_STRING = 0x0C, - NUMERIC_STRING = 0x12, - PRINTABLE_STRING = 0x13, - T61_STRING = 0x14, - IA5_STRING = 0x16, - VISIBLE_STRING = 0x1A, - UNIVERSAL_STRING = 0x1C, - BMP_STRING = 0x1E, + UTF8_STRING = 0x0C, + NUMERIC_STRING = 0x12, + PRINTABLE_STRING = 0x13, + T61_STRING = 0x14, + IA5_STRING = 0x16, + VISIBLE_STRING = 0x1A, + UNIVERSAL_STRING = 0x1C, + BMP_STRING = 0x1E, - UTC_TIME = 0x17, - GENERALIZED_TIME = 0x18, - UTC_OR_GENERALIZED_TIME = 0x19, + UTC_TIME = 0x17, + GENERALIZED_TIME = 0x18, + UTC_OR_GENERALIZED_TIME = 0x19, - NO_OBJECT = 0xFF00, - DIRECTORY_STRING = 0xFF01 + NO_OBJECT = 0xFF00, + DIRECTORY_STRING = 0xFF01 }; std::string BOTAN_UNSTABLE_API asn1_tag_to_string(ASN1_Tag type); std::string BOTAN_UNSTABLE_API asn1_class_to_string(ASN1_Tag type); /** -* Basic ASN.1 Object Interface -*/ -class BOTAN_PUBLIC_API(2,0) ASN1_Object - { + * Basic ASN.1 Object Interface + */ +class BOTAN_PUBLIC_API(2, 0) ASN1_Object { public: - /** - * Encode whatever this object is into to - * @param to the DER_Encoder that will be written to - */ - virtual void encode_into(DER_Encoder& to) const = 0; + /** + * Encode whatever this object is into to + * @param to the DER_Encoder that will be written to + */ + virtual void encode_into(DER_Encoder& to) const = 0; - /** - * Decode whatever this object is from from - * @param from the BER_Decoder that will be read from - */ - virtual void decode_from(BER_Decoder& from) = 0; + /** + * Decode whatever this object is from from + * @param from the BER_Decoder that will be read from + */ + virtual void decode_from(BER_Decoder& from) = 0; - /** - * Return the encoding of this object. This is a convenience - * method when just one object needs to be serialized. Use - * DER_Encoder for complicated encodings. - */ - std::vector BER_encode() const; + /** + * Return the encoding of this object. This is a convenience + * method when just one object needs to be serialized. Use + * DER_Encoder for complicated encodings. + */ + std::vector BER_encode() const; - ASN1_Object() = default; - ASN1_Object(const ASN1_Object&) = default; - ASN1_Object & operator=(const ASN1_Object&) = default; - virtual ~ASN1_Object() = default; - }; + ASN1_Object() = default; + ASN1_Object(const ASN1_Object&) = default; + ASN1_Object& operator=(const ASN1_Object&) = default; + virtual ~ASN1_Object() = default; +}; /** -* BER Encoded Object -*/ -class BOTAN_PUBLIC_API(2,0) BER_Object final - { + * BER Encoded Object + */ +class BOTAN_PUBLIC_API(2, 0) BER_Object final { public: - BER_Object() : type_tag(NO_OBJECT), class_tag(UNIVERSAL) {} + BER_Object() : type_tag(NO_OBJECT), class_tag(UNIVERSAL) {} - BER_Object(const BER_Object& other) = default; + BER_Object(const BER_Object& other) = default; - BER_Object& operator=(const BER_Object& other) = default; + BER_Object& operator=(const BER_Object& other) = default; - BER_Object(BER_Object&& other) = default; + BER_Object(BER_Object&& other) = default; - BER_Object& operator=(BER_Object&& other) = default; + BER_Object& operator=(BER_Object&& other) = default; - bool is_set() const { return type_tag != NO_OBJECT; } + bool is_set() const { return type_tag != NO_OBJECT; } - ASN1_Tag tagging() const { return ASN1_Tag(type() | get_class()); } + ASN1_Tag tagging() const { return ASN1_Tag(type() | get_class()); } - ASN1_Tag type() const { return type_tag; } - ASN1_Tag get_class() const { return class_tag; } + ASN1_Tag type() const { return type_tag; } + ASN1_Tag get_class() const { return class_tag; } - const uint8_t* bits() const { return value.data(); } + const uint8_t* bits() const { return value.data(); } - size_t length() const { return value.size(); } + size_t length() const { return value.size(); } - void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag, - const std::string& descr = "object") const; + void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::string& descr = "object") const; - bool is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const; + bool is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const; - bool is_a(int type_tag, ASN1_Tag class_tag) const; + bool is_a(int type_tag, ASN1_Tag class_tag) const; - BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES: - /* - * The following member variables are public for historical reasons, but - * will be made private in a future major release. Use the accessor - * functions above. - */ - ASN1_Tag type_tag, class_tag; - secure_vector value; + BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES : + /* + * The following member variables are public for historical reasons, but + * will be made private in a future major release. Use the accessor + * functions above. + */ + ASN1_Tag type_tag, + class_tag; + secure_vector value; private: + friend class BER_Decoder; - friend class BER_Decoder; + void set_tagging(ASN1_Tag type_tag, ASN1_Tag class_tag); - void set_tagging(ASN1_Tag type_tag, ASN1_Tag class_tag); - - uint8_t* mutable_bits(size_t length) - { - value.resize(length); - return value.data(); - } - }; + uint8_t* mutable_bits(size_t length) { + value.resize(length); + return value.data(); + } +}; /* -* ASN.1 Utility Functions -*/ + * ASN.1 Utility Functions + */ class DataSource; namespace ASN1 { @@ -2465,464 +2282,424 @@ std::vector put_in_sequence(const uint8_t bits[], size_t len); std::string to_string(const BER_Object& obj); /** -* Heuristics tests; is this object possibly BER? -* @param src a data source that will be peeked at but not modified -*/ + * Heuristics tests; is this object possibly BER? + * @param src a data source that will be peeked at but not modified + */ bool maybe_BER(DataSource& src); -} +} // namespace ASN1 /** -* General BER Decoding Error Exception -*/ -class BOTAN_PUBLIC_API(2,0) BER_Decoding_Error : public Decoding_Error - { + * General BER Decoding Error Exception + */ +class BOTAN_PUBLIC_API(2, 0) BER_Decoding_Error : public Decoding_Error { public: - explicit BER_Decoding_Error(const std::string&); - }; + explicit BER_Decoding_Error(const std::string&); +}; /** -* Exception For Incorrect BER Taggings -*/ -class BOTAN_PUBLIC_API(2,0) BER_Bad_Tag final : public BER_Decoding_Error - { + * Exception For Incorrect BER Taggings + */ +class BOTAN_PUBLIC_API(2, 0) BER_Bad_Tag final : public BER_Decoding_Error { public: - BER_Bad_Tag(const std::string& msg, ASN1_Tag tag); - BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2); - }; + BER_Bad_Tag(const std::string& msg, ASN1_Tag tag); + BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2); +}; -} +} // namespace Botan namespace Botan { /** -* This class represents ASN.1 object identifiers. -*/ -class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object - { + * This class represents ASN.1 object identifiers. + */ +class BOTAN_PUBLIC_API(2, 0) OID final : public ASN1_Object { public: + /** + * Create an uninitialied OID object + */ + explicit OID() {} - /** - * Create an uninitialied OID object - */ - explicit OID() {} + /** + * Construct an OID from a string. + * @param str a string in the form "a.b.c" etc., where a,b,c are numbers + */ + explicit OID(const std::string& str); - /** - * Construct an OID from a string. - * @param str a string in the form "a.b.c" etc., where a,b,c are numbers - */ - explicit OID(const std::string& str); + /** + * Initialize an OID from a sequence of integer values + */ + explicit OID(std::initializer_list init) : m_id(init) {} - /** - * Initialize an OID from a sequence of integer values - */ - explicit OID(std::initializer_list init) : m_id(init) {} + /** + * Initialize an OID from a vector of integer values + */ + explicit OID(std::vector&& init) : m_id(init) {} - /** - * Initialize an OID from a vector of integer values - */ - explicit OID(std::vector&& init) : m_id(init) {} + /** + * Construct an OID from a string. + * @param str a string in the form "a.b.c" etc., where a,b,c are numbers + * or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier") + */ + static OID from_string(const std::string& str); - /** - * Construct an OID from a string. - * @param str a string in the form "a.b.c" etc., where a,b,c are numbers - * or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier") - */ - static OID from_string(const std::string& str); + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; - void encode_into(class DER_Encoder&) const override; - void decode_from(class BER_Decoder&) override; + /** + * Find out whether this OID is empty + * @return true is no OID value is set + */ + bool empty() const { return m_id.empty(); } - /** - * Find out whether this OID is empty - * @return true is no OID value is set - */ - bool empty() const { return m_id.empty(); } + /** + * Find out whether this OID has a value + * @return true is this OID has a value + */ + bool has_value() const { return (m_id.empty() == false); } - /** - * Find out whether this OID has a value - * @return true is this OID has a value - */ - bool has_value() const { return (m_id.empty() == false); } + /** + * Get this OID as list (vector) of its components. + * @return vector representing this OID + */ + const std::vector& get_components() const { return m_id; } - /** - * Get this OID as list (vector) of its components. - * @return vector representing this OID - */ - const std::vector& get_components() const { return m_id; } + const std::vector& get_id() const { return get_components(); } - const std::vector& get_id() const { return get_components(); } + /** + * Get this OID as a string + * @return string representing this OID + */ + std::string BOTAN_DEPRECATED("Use OID::to_string") as_string() const { + return this->to_string(); + } - /** - * Get this OID as a string - * @return string representing this OID - */ - std::string BOTAN_DEPRECATED("Use OID::to_string") as_string() const - { - return this->to_string(); - } + /** + * Get this OID as a dotted-decimal string + * @return string representing this OID + */ + std::string to_string() const; - /** - * Get this OID as a dotted-decimal string - * @return string representing this OID - */ - std::string to_string() const; + /** + * If there is a known name associated with this OID, return that. + * Otherwise return the result of to_string + */ + std::string to_formatted_string() const; - /** - * If there is a known name associated with this OID, return that. - * Otherwise return the result of to_string - */ - std::string to_formatted_string() const; + /** + * Compare two OIDs. + * @return true if they are equal, false otherwise + */ + bool operator==(const OID& other) const { return m_id == other.m_id; } - /** - * Compare two OIDs. - * @return true if they are equal, false otherwise - */ - bool operator==(const OID& other) const - { - return m_id == other.m_id; - } + /** + * Reset this instance to an empty OID. + */ + void BOTAN_DEPRECATED("Avoid mutation of OIDs") clear() { m_id.clear(); } - /** - * Reset this instance to an empty OID. - */ - void BOTAN_DEPRECATED("Avoid mutation of OIDs") clear() { m_id.clear(); } - - /** - * Add a component to this OID. - * @param new_comp the new component to add to the end of this OID - * @return reference to *this - */ - BOTAN_DEPRECATED("Avoid mutation of OIDs") OID& operator+=(uint32_t new_comp) - { - m_id.push_back(new_comp); - return (*this); - } + /** + * Add a component to this OID. + * @param new_comp the new component to add to the end of this OID + * @return reference to *this + */ + BOTAN_DEPRECATED("Avoid mutation of OIDs") OID& operator+=(uint32_t new_comp) { + m_id.push_back(new_comp); + return (*this); + } private: - std::vector m_id; - }; + std::vector m_id; +}; /** -* Append another component onto the OID. -* @param oid the OID to add the new component to -* @param new_comp the new component to add -*/ -OID BOTAN_PUBLIC_API(2,0) operator+(const OID& oid, uint32_t new_comp); + * Append another component onto the OID. + * @param oid the OID to add the new component to + * @param new_comp the new component to add + */ +OID BOTAN_PUBLIC_API(2, 0) operator+(const OID & oid, uint32_t new_comp); /** -* Compare two OIDs. -* @param a the first OID -* @param b the second OID -* @return true if a is not equal to b -*/ -inline bool operator!=(const OID& a, const OID& b) - { - return !(a == b); - } + * Compare two OIDs. + * @param a the first OID + * @param b the second OID + * @return true if a is not equal to b + */ +inline bool operator!=(const OID& a, const OID& b) { return !(a == b); } /** -* Compare two OIDs. -* @param a the first OID -* @param b the second OID -* @return true if a is lexicographically smaller than b -*/ -bool BOTAN_PUBLIC_API(2,0) operator<(const OID& a, const OID& b); + * Compare two OIDs. + * @param a the first OID + * @param b the second OID + * @return true if a is lexicographically smaller than b + */ +bool BOTAN_PUBLIC_API(2, 0) operator<(const OID & a, const OID & b); -} +} // namespace Botan namespace Botan { /** -* Algorithm Identifier -*/ -class BOTAN_PUBLIC_API(2,0) AlgorithmIdentifier final : public ASN1_Object - { + * Algorithm Identifier + */ +class BOTAN_PUBLIC_API(2, 0) AlgorithmIdentifier final : public ASN1_Object { public: - enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM }; + enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM }; - void encode_into(class DER_Encoder&) const override; - void decode_from(class BER_Decoder&) override; + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; - AlgorithmIdentifier() = default; + AlgorithmIdentifier() = default; - AlgorithmIdentifier(const OID& oid, Encoding_Option enc); - AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc); + AlgorithmIdentifier(const OID& oid, Encoding_Option enc); + AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc); - AlgorithmIdentifier(const OID& oid, const std::vector& params); - AlgorithmIdentifier(const std::string& oid_name, const std::vector& params); + AlgorithmIdentifier(const OID& oid, const std::vector& params); + AlgorithmIdentifier(const std::string& oid_name, const std::vector& params); - const OID& get_oid() const { return oid; } - const std::vector& get_parameters() const { return parameters; } + const OID& get_oid() const { return oid; } + const std::vector& get_parameters() const { return parameters; } - BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES: - /* - * These values are public for historical reasons, but in a future release - * they will be made private. Do not access them. - */ - OID oid; - std::vector parameters; - }; + BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES : + /* + * These values are public for historical reasons, but in a future release + * they will be made private. Do not access them. + */ + OID oid; + std::vector parameters; +}; /* -* Comparison Operations -*/ -bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&, - const AlgorithmIdentifier&); -bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&, - const AlgorithmIdentifier&); + * Comparison Operations + */ +bool BOTAN_PUBLIC_API(2, 0) operator==(const AlgorithmIdentifier&, const AlgorithmIdentifier&); +bool BOTAN_PUBLIC_API(2, 0) operator!=(const AlgorithmIdentifier&, const AlgorithmIdentifier&); -} +} // namespace Botan namespace Botan { /** -* Attribute -*/ -class BOTAN_PUBLIC_API(2,0) Attribute final : public ASN1_Object - { + * Attribute + */ +class BOTAN_PUBLIC_API(2, 0) Attribute final : public ASN1_Object { public: - void encode_into(class DER_Encoder& to) const override; - void decode_from(class BER_Decoder& from) override; + void encode_into(class DER_Encoder& to) const override; + void decode_from(class BER_Decoder& from) override; - Attribute() = default; - Attribute(const OID&, const std::vector&); - Attribute(const std::string&, const std::vector&); + Attribute() = default; + Attribute(const OID&, const std::vector&); + Attribute(const std::string&, const std::vector&); - const OID& get_oid() const { return oid; } + const OID& get_oid() const { return oid; } - const std::vector& get_parameters() const { return parameters; } + const std::vector& get_parameters() const { return parameters; } - BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES: - /* - * These values are public for historical reasons, but in a future release - * they will be made private. Do not access them. - */ - OID oid; - std::vector parameters; - }; + BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES : + /* + * These values are public for historical reasons, but in a future release + * they will be made private. Do not access them. + */ + OID oid; + std::vector parameters; +}; -} +} // namespace Botan namespace Botan { class BER_Decoder; /** -* Format ASN.1 data and call a virtual to format -*/ -class BOTAN_PUBLIC_API(2,4) ASN1_Formatter - { + * Format ASN.1 data and call a virtual to format + */ +class BOTAN_PUBLIC_API(2, 4) ASN1_Formatter { public: - virtual ~ASN1_Formatter() = default; + virtual ~ASN1_Formatter() = default; - /** - * @param print_context_specific if true, try to parse nested context specific data. - * @param max_depth do not recurse more than this many times. If zero, recursion - * is unbounded. - */ - ASN1_Formatter(bool print_context_specific, size_t max_depth) : - m_print_context_specific(print_context_specific), - m_max_depth(max_depth) - {} + /** + * @param print_context_specific if true, try to parse nested context specific data. + * @param max_depth do not recurse more than this many times. If zero, recursion + * is unbounded. + */ + ASN1_Formatter(bool print_context_specific, size_t max_depth) + : m_print_context_specific(print_context_specific), m_max_depth(max_depth) {} - void print_to_stream(std::ostream& out, - const uint8_t in[], - size_t len) const; + void print_to_stream(std::ostream& out, const uint8_t in[], size_t len) const; - std::string print(const uint8_t in[], size_t len) const; + std::string print(const uint8_t in[], size_t len) const; - template - std::string print(const std::vector& vec) const - { - return print(vec.data(), vec.size()); - } + template + std::string print(const std::vector& vec) const { + return print(vec.data(), vec.size()); + } protected: - /** - * This is called for each element - */ - virtual std::string format(ASN1_Tag type_tag, - ASN1_Tag class_tag, - size_t level, - size_t length, - const std::string& value) const = 0; + /** + * This is called for each element + */ + virtual std::string format(ASN1_Tag type_tag, ASN1_Tag class_tag, size_t level, size_t length, + const std::string& value) const = 0; - /** - * This is called to format binary elements that we don't know how to - * convert to a string The result will be passed as value to format; the - * tags are included as a hint to aid decoding. - */ - virtual std::string format_bin(ASN1_Tag type_tag, - ASN1_Tag class_tag, - const std::vector& vec) const = 0; + /** + * This is called to format binary elements that we don't know how to + * convert to a string The result will be passed as value to format; the + * tags are included as a hint to aid decoding. + */ + virtual std::string format_bin(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::vector& vec) const = 0; private: - void decode(std::ostream& output, - BER_Decoder& decoder, - size_t level) const; + void decode(std::ostream& output, BER_Decoder& decoder, size_t level) const; - const bool m_print_context_specific; - const size_t m_max_depth; - }; + const bool m_print_context_specific; + const size_t m_max_depth; +}; /** -* Format ASN.1 data into human readable output. The exact form of the output for -* any particular input is not guaranteed and may change from release to release. -*/ -class BOTAN_PUBLIC_API(2,4) ASN1_Pretty_Printer final : public ASN1_Formatter - { + * Format ASN.1 data into human readable output. The exact form of the output for + * any particular input is not guaranteed and may change from release to release. + */ +class BOTAN_PUBLIC_API(2, 4) ASN1_Pretty_Printer final : public ASN1_Formatter { public: - /** - * @param print_limit strings larger than this are not printed - * @param print_binary_limit binary strings larger than this are not printed - * @param print_context_specific if true, try to parse nested context specific data. - * @param initial_level the initial depth (0 or 1 are the only reasonable values) - * @param value_column ASN.1 values are lined up at this column in output - * @param max_depth do not recurse more than this many times. If zero, recursion - * is unbounded. - */ - ASN1_Pretty_Printer(size_t print_limit = 4096, - size_t print_binary_limit = 2048, - bool print_context_specific = true, - size_t initial_level = 0, - size_t value_column = 60, - size_t max_depth = 64) : - ASN1_Formatter(print_context_specific, max_depth), - m_print_limit(print_limit), - m_print_binary_limit(print_binary_limit), - m_initial_level(initial_level), - m_value_column(value_column) - {} + /** + * @param print_limit strings larger than this are not printed + * @param print_binary_limit binary strings larger than this are not printed + * @param print_context_specific if true, try to parse nested context specific data. + * @param initial_level the initial depth (0 or 1 are the only reasonable values) + * @param value_column ASN.1 values are lined up at this column in output + * @param max_depth do not recurse more than this many times. If zero, recursion + * is unbounded. + */ + ASN1_Pretty_Printer(size_t print_limit = 4096, size_t print_binary_limit = 2048, + bool print_context_specific = true, size_t initial_level = 0, + size_t value_column = 60, size_t max_depth = 64) + : ASN1_Formatter(print_context_specific, max_depth), + m_print_limit(print_limit), + m_print_binary_limit(print_binary_limit), + m_initial_level(initial_level), + m_value_column(value_column) {} private: - std::string format(ASN1_Tag type_tag, - ASN1_Tag class_tag, - size_t level, - size_t length, - const std::string& value) const override; + std::string format(ASN1_Tag type_tag, ASN1_Tag class_tag, size_t level, size_t length, + const std::string& value) const override; - std::string format_bin(ASN1_Tag type_tag, - ASN1_Tag class_tag, - const std::vector& vec) const override; + std::string format_bin(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::vector& vec) const override; - const size_t m_print_limit; - const size_t m_print_binary_limit; - const size_t m_initial_level; - const size_t m_value_column; - }; + const size_t m_print_limit; + const size_t m_print_binary_limit; + const size_t m_initial_level; + const size_t m_value_column; +}; -} +} // namespace Botan namespace Botan { /** -* ASN.1 string type -* This class normalizes all inputs to a UTF-8 std::string -*/ -class BOTAN_PUBLIC_API(2,0) ASN1_String final : public ASN1_Object - { + * ASN.1 string type + * This class normalizes all inputs to a UTF-8 std::string + */ +class BOTAN_PUBLIC_API(2, 0) ASN1_String final : public ASN1_Object { public: - void encode_into(class DER_Encoder&) const override; - void decode_from(class BER_Decoder&) override; + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; - ASN1_Tag tagging() const { return m_tag; } + ASN1_Tag tagging() const { return m_tag; } - const std::string& value() const { return m_utf8_str; } + const std::string& value() const { return m_utf8_str; } - size_t size() const { return value().size(); } + size_t size() const { return value().size(); } - bool empty() const { return m_utf8_str.empty(); } + bool empty() const { return m_utf8_str.empty(); } - std::string BOTAN_DEPRECATED("Use value() to get UTF-8 string instead") - iso_8859() const; + std::string BOTAN_DEPRECATED("Use value() to get UTF-8 string instead") iso_8859() const; - /** - * Return true iff this is a tag for a known string type we can handle. - * This ignores string types that are not supported, eg teletexString - */ - static bool is_string_type(ASN1_Tag tag); + /** + * Return true iff this is a tag for a known string type we can handle. + * This ignores string types that are not supported, eg teletexString + */ + static bool is_string_type(ASN1_Tag tag); - bool operator==(const ASN1_String& other) const - { return value() == other.value(); } + bool operator==(const ASN1_String& other) const { return value() == other.value(); } + + explicit ASN1_String(const std::string& utf8 = ""); + ASN1_String(const std::string& utf8, ASN1_Tag tag); - explicit ASN1_String(const std::string& utf8 = ""); - ASN1_String(const std::string& utf8, ASN1_Tag tag); private: - std::vector m_data; - std::string m_utf8_str; - ASN1_Tag m_tag; - }; + std::vector m_data; + std::string m_utf8_str; + ASN1_Tag m_tag; +}; -} +} // namespace Botan namespace Botan { /** -* X.509 Time -*/ -class BOTAN_PUBLIC_API(2,0) X509_Time final : public ASN1_Object - { + * X.509 Time + */ +class BOTAN_PUBLIC_API(2, 0) X509_Time final : public ASN1_Object { public: - /// DER encode a X509_Time - void encode_into(DER_Encoder&) const override; + /// DER encode a X509_Time + void encode_into(DER_Encoder&) const override; - // Decode a BER encoded X509_Time - void decode_from(BER_Decoder&) override; + // Decode a BER encoded X509_Time + void decode_from(BER_Decoder&) override; - /// Return an internal string representation of the time - std::string to_string() const; + /// Return an internal string representation of the time + std::string to_string() const; - /// Returns a human friendly string replesentation of no particular formatting - std::string readable_string() const; + /// Returns a human friendly string replesentation of no particular formatting + std::string readable_string() const; - /// Return if the time has been set somehow - bool time_is_set() const; + /// Return if the time has been set somehow + bool time_is_set() const; - /// Compare this time against another - int32_t cmp(const X509_Time& other) const; + /// Compare this time against another + int32_t cmp(const X509_Time& other) const; - /// Create an invalid X509_Time - X509_Time() = default; + /// Create an invalid X509_Time + X509_Time() = default; - /// Create a X509_Time from a time point - explicit X509_Time(const std::chrono::system_clock::time_point& time); + /// Create a X509_Time from a time point + explicit X509_Time(const std::chrono::system_clock::time_point& time); - /// Create an X509_Time from string - X509_Time(const std::string& t_spec, ASN1_Tag tag); + /// Create an X509_Time from string + X509_Time(const std::string& t_spec, ASN1_Tag tag); - /// Returns a STL timepoint object - std::chrono::system_clock::time_point to_std_timepoint() const; + /// Returns a STL timepoint object + std::chrono::system_clock::time_point to_std_timepoint() const; - /// Return time since epoch - uint64_t time_since_epoch() const; + /// Return time since epoch + uint64_t time_since_epoch() const; private: - void set_to(const std::string& t_spec, ASN1_Tag); - bool passes_sanity_check() const; + void set_to(const std::string& t_spec, ASN1_Tag); + bool passes_sanity_check() const; - uint32_t m_year = 0; - uint32_t m_month = 0; - uint32_t m_day = 0; - uint32_t m_hour = 0; - uint32_t m_minute = 0; - uint32_t m_second = 0; - ASN1_Tag m_tag = NO_OBJECT; - }; + uint32_t m_year = 0; + uint32_t m_month = 0; + uint32_t m_day = 0; + uint32_t m_hour = 0; + uint32_t m_minute = 0; + uint32_t m_second = 0; + ASN1_Tag m_tag = NO_OBJECT; +}; /* -* Comparison Operations -*/ -bool BOTAN_PUBLIC_API(2,0) operator==(const X509_Time&, const X509_Time&); -bool BOTAN_PUBLIC_API(2,0) operator!=(const X509_Time&, const X509_Time&); -bool BOTAN_PUBLIC_API(2,0) operator<=(const X509_Time&, const X509_Time&); -bool BOTAN_PUBLIC_API(2,0) operator>=(const X509_Time&, const X509_Time&); -bool BOTAN_PUBLIC_API(2,0) operator<(const X509_Time&, const X509_Time&); -bool BOTAN_PUBLIC_API(2,0) operator>(const X509_Time&, const X509_Time&); + * Comparison Operations + */ +bool BOTAN_PUBLIC_API(2, 0) operator==(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2, 0) operator!=(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2, 0) operator<=(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2, 0) operator>=(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2, 0) operator<(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2, 0) operator>(const X509_Time&, const X509_Time&); typedef X509_Time ASN1_Time; -} +} // namespace Botan namespace Botan { @@ -2939,31 +2716,27 @@ namespace Botan { padding chars will be applied if needed * @return number of bytes written to output */ -size_t BOTAN_PUBLIC_API(2,0) base64_encode(char output[], - const uint8_t input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs); +size_t BOTAN_PUBLIC_API(2, 0) + base64_encode(char output[], const uint8_t input[], size_t input_length, size_t& input_consumed, + bool final_inputs); /** -* Perform base64 encoding -* @param input some input -* @param input_length length of input in bytes -* @return base64adecimal representation of input -*/ -std::string BOTAN_PUBLIC_API(2,0) base64_encode(const uint8_t input[], - size_t input_length); + * Perform base64 encoding + * @param input some input + * @param input_length length of input in bytes + * @return base64adecimal representation of input + */ +std::string BOTAN_PUBLIC_API(2, 0) base64_encode(const uint8_t input[], size_t input_length); /** -* Perform base64 encoding -* @param input some input -* @return base64adecimal representation of input -*/ -template -std::string base64_encode(const std::vector& input) - { - return base64_encode(input.data(), input.size()); - } + * Perform base64 encoding + * @param input some input + * @return base64adecimal representation of input + */ +template +std::string base64_encode(const std::vector& input) { + return base64_encode(input.data(), input.size()); +} /** * Perform base64 decoding @@ -2980,12 +2753,9 @@ std::string base64_encode(const std::vector& input) exception if whitespace is encountered * @return number of bytes written to output */ -size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs, - bool ignore_ws = true); +size_t BOTAN_PUBLIC_API(2, 0) + base64_decode(uint8_t output[], const char input[], size_t input_length, size_t& input_consumed, + bool final_inputs, bool ignore_ws = true); /** * Perform base64 decoding @@ -2996,10 +2766,8 @@ size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], exception if whitespace is encountered * @return number of bytes written to output */ -size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], - const char input[], - size_t input_length, - bool ignore_ws = true); +size_t BOTAN_PUBLIC_API(2, 0) + base64_decode(uint8_t output[], const char input[], size_t input_length, bool ignore_ws = true); /** * Perform base64 decoding @@ -3009,9 +2777,8 @@ size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], exception if whitespace is encountered * @return number of bytes written to output */ -size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], - const std::string& input, - bool ignore_ws = true); +size_t BOTAN_PUBLIC_API(2, 0) + base64_decode(uint8_t output[], const std::string& input, bool ignore_ws = true); /** * Perform base64 decoding @@ -3021,9 +2788,8 @@ size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], exception if whitespace is encountered * @return decoded base64 output */ -secure_vector BOTAN_PUBLIC_API(2,0) base64_decode(const char input[], - size_t input_length, - bool ignore_ws = true); +secure_vector BOTAN_PUBLIC_API(2, 0) + base64_decode(const char input[], size_t input_length, bool ignore_ws = true); /** * Perform base64 decoding @@ -3032,691 +2798,609 @@ secure_vector BOTAN_PUBLIC_API(2,0) base64_decode(const char input[], exception if whitespace is encountered * @return decoded base64 output */ -secure_vector BOTAN_PUBLIC_API(2,0) base64_decode(const std::string& input, - bool ignore_ws = true); +secure_vector BOTAN_PUBLIC_API(2, 0) + base64_decode(const std::string& input, bool ignore_ws = true); /** -* Calculate the size of output buffer for base64_encode -* @param input_length the length of input in bytes -* @return the size of output buffer in bytes -*/ -size_t BOTAN_PUBLIC_API(2,1) base64_encode_max_output(size_t input_length); + * Calculate the size of output buffer for base64_encode + * @param input_length the length of input in bytes + * @return the size of output buffer in bytes + */ +size_t BOTAN_PUBLIC_API(2, 1) base64_encode_max_output(size_t input_length); /** -* Calculate the size of output buffer for base64_decode -* @param input_length the length of input in bytes -* @return the size of output buffer in bytes -*/ -size_t BOTAN_PUBLIC_API(2,1) base64_decode_max_output(size_t input_length); + * Calculate the size of output buffer for base64_decode + * @param input_length the length of input in bytes + * @return the size of output buffer in bytes + */ +size_t BOTAN_PUBLIC_API(2, 1) base64_decode_max_output(size_t input_length); -} +} // namespace Botan namespace Botan { /** -* This class represents an abstract data source object. -*/ -class BOTAN_PUBLIC_API(2,0) DataSource - { + * This class represents an abstract data source object. + */ +class BOTAN_PUBLIC_API(2, 0) DataSource { public: - /** - * Read from the source. Moves the internal offset so that every - * call to read will return a new portion of the source. - * - * @param out the byte array to write the result to - * @param length the length of the byte array out - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t read(uint8_t out[], size_t length) BOTAN_WARN_UNUSED_RESULT = 0; + /** + * Read from the source. Moves the internal offset so that every + * call to read will return a new portion of the source. + * + * @param out the byte array to write the result to + * @param length the length of the byte array out + * @return length in bytes that was actually read and put + * into out + */ + virtual size_t read(uint8_t out[], size_t length) BOTAN_WARN_UNUSED_RESULT = 0; - virtual bool check_available(size_t n) = 0; + virtual bool check_available(size_t n) = 0; - /** - * Read from the source but do not modify the internal - * offset. Consecutive calls to peek() will return portions of - * the source starting at the same position. - * - * @param out the byte array to write the output to - * @param length the length of the byte array out - * @param peek_offset the offset into the stream to read at - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t peek(uint8_t out[], size_t length, size_t peek_offset) const BOTAN_WARN_UNUSED_RESULT = 0; + /** + * Read from the source but do not modify the internal + * offset. Consecutive calls to peek() will return portions of + * the source starting at the same position. + * + * @param out the byte array to write the output to + * @param length the length of the byte array out + * @param peek_offset the offset into the stream to read at + * @return length in bytes that was actually read and put + * into out + */ + virtual size_t peek(uint8_t out[], size_t length, + size_t peek_offset) const BOTAN_WARN_UNUSED_RESULT = 0; - /** - * Test whether the source still has data that can be read. - * @return true if there is no more data to read, false otherwise - */ - virtual bool end_of_data() const = 0; - /** - * return the id of this data source - * @return std::string representing the id of this data source - */ - virtual std::string id() const { return ""; } + /** + * Test whether the source still has data that can be read. + * @return true if there is no more data to read, false otherwise + */ + virtual bool end_of_data() const = 0; + /** + * return the id of this data source + * @return std::string representing the id of this data source + */ + virtual std::string id() const { return ""; } - /** - * Read one byte. - * @param out the byte to read to - * @return length in bytes that was actually read and put - * into out - */ - size_t read_byte(uint8_t& out); + /** + * Read one byte. + * @param out the byte to read to + * @return length in bytes that was actually read and put + * into out + */ + size_t read_byte(uint8_t& out); - /** - * Peek at one byte. - * @param out an output byte - * @return length in bytes that was actually read and put - * into out - */ - size_t peek_byte(uint8_t& out) const; + /** + * Peek at one byte. + * @param out an output byte + * @return length in bytes that was actually read and put + * into out + */ + size_t peek_byte(uint8_t& out) const; - /** - * Discard the next N bytes of the data - * @param N the number of bytes to discard - * @return number of bytes actually discarded - */ - size_t discard_next(size_t N); + /** + * Discard the next N bytes of the data + * @param N the number of bytes to discard + * @return number of bytes actually discarded + */ + size_t discard_next(size_t N); - /** - * @return number of bytes read so far. - */ - virtual size_t get_bytes_read() const = 0; + /** + * @return number of bytes read so far. + */ + virtual size_t get_bytes_read() const = 0; - DataSource() = default; - virtual ~DataSource() = default; - DataSource& operator=(const DataSource&) = delete; - DataSource(const DataSource&) = delete; - }; + DataSource() = default; + virtual ~DataSource() = default; + DataSource& operator=(const DataSource&) = delete; + DataSource(const DataSource&) = delete; +}; /** -* This class represents a Memory-Based DataSource -*/ -class BOTAN_PUBLIC_API(2,0) DataSource_Memory final : public DataSource - { + * This class represents a Memory-Based DataSource + */ +class BOTAN_PUBLIC_API(2, 0) DataSource_Memory final : public DataSource { public: - size_t read(uint8_t[], size_t) override; - size_t peek(uint8_t[], size_t, size_t) const override; - bool check_available(size_t n) override; - bool end_of_data() const override; + size_t read(uint8_t[], size_t) override; + size_t peek(uint8_t[], size_t, size_t) const override; + bool check_available(size_t n) override; + bool end_of_data() const override; - /** - * Construct a memory source that reads from a string - * @param in the string to read from - */ - explicit DataSource_Memory(const std::string& in); + /** + * Construct a memory source that reads from a string + * @param in the string to read from + */ + explicit DataSource_Memory(const std::string& in); - /** - * Construct a memory source that reads from a byte array - * @param in the byte array to read from - * @param length the length of the byte array - */ - DataSource_Memory(const uint8_t in[], size_t length) : - m_source(in, in + length), m_offset(0) {} + /** + * Construct a memory source that reads from a byte array + * @param in the byte array to read from + * @param length the length of the byte array + */ + DataSource_Memory(const uint8_t in[], size_t length) : m_source(in, in + length), m_offset(0) {} - /** - * Construct a memory source that reads from a secure_vector - * @param in the MemoryRegion to read from - */ - explicit DataSource_Memory(const secure_vector& in) : - m_source(in), m_offset(0) {} + /** + * Construct a memory source that reads from a secure_vector + * @param in the MemoryRegion to read from + */ + explicit DataSource_Memory(const secure_vector& in) : m_source(in), m_offset(0) {} - /** - * Construct a memory source that reads from a std::vector - * @param in the MemoryRegion to read from - */ - explicit DataSource_Memory(const std::vector& in) : - m_source(in.begin(), in.end()), m_offset(0) {} + /** + * Construct a memory source that reads from a std::vector + * @param in the MemoryRegion to read from + */ + explicit DataSource_Memory(const std::vector& in) + : m_source(in.begin(), in.end()), m_offset(0) {} + + size_t get_bytes_read() const override { return m_offset; } - size_t get_bytes_read() const override { return m_offset; } private: - secure_vector m_source; - size_t m_offset; - }; + secure_vector m_source; + size_t m_offset; +}; /** -* This class represents a Stream-Based DataSource. -*/ -class BOTAN_PUBLIC_API(2,0) DataSource_Stream final : public DataSource - { + * This class represents a Stream-Based DataSource. + */ +class BOTAN_PUBLIC_API(2, 0) DataSource_Stream final : public DataSource { public: - size_t read(uint8_t[], size_t) override; - size_t peek(uint8_t[], size_t, size_t) const override; - bool check_available(size_t n) override; - bool end_of_data() const override; - std::string id() const override; + size_t read(uint8_t[], size_t) override; + size_t peek(uint8_t[], size_t, size_t) const override; + bool check_available(size_t n) override; + bool end_of_data() const override; + std::string id() const override; - DataSource_Stream(std::istream&, - const std::string& id = ""); + DataSource_Stream(std::istream&, const std::string& id = ""); #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) - /** - * Construct a Stream-Based DataSource from filesystem path - * @param file the path to the file - * @param use_binary whether to treat the file as binary or not - */ - DataSource_Stream(const std::string& file, bool use_binary = false); + /** + * Construct a Stream-Based DataSource from filesystem path + * @param file the path to the file + * @param use_binary whether to treat the file as binary or not + */ + DataSource_Stream(const std::string& file, bool use_binary = false); #endif - DataSource_Stream(const DataSource_Stream&) = delete; + DataSource_Stream(const DataSource_Stream&) = delete; - DataSource_Stream& operator=(const DataSource_Stream&) = delete; + DataSource_Stream& operator=(const DataSource_Stream&) = delete; - ~DataSource_Stream(); + ~DataSource_Stream(); + + size_t get_bytes_read() const override { return m_total_read; } - size_t get_bytes_read() const override { return m_total_read; } private: - const std::string m_identifier; + const std::string m_identifier; - std::unique_ptr m_source_memory; - std::istream& m_source; - size_t m_total_read; - }; + std::unique_ptr m_source_memory; + std::istream& m_source; + size_t m_total_read; +}; -} +} // namespace Botan namespace Botan { class BigInt; /** -* BER Decoding Object -*/ -class BOTAN_PUBLIC_API(2,0) BER_Decoder final - { + * BER Decoding Object + */ +class BOTAN_PUBLIC_API(2, 0) BER_Decoder final { public: - /** - * Set up to BER decode the data in buf of length len - */ - BER_Decoder(const uint8_t buf[], size_t len); + /** + * Set up to BER decode the data in buf of length len + */ + BER_Decoder(const uint8_t buf[], size_t len); - /** - * Set up to BER decode the data in vec - */ - explicit BER_Decoder(const secure_vector& vec); + /** + * Set up to BER decode the data in vec + */ + explicit BER_Decoder(const secure_vector& vec); - /** - * Set up to BER decode the data in vec - */ - explicit BER_Decoder(const std::vector& vec); + /** + * Set up to BER decode the data in vec + */ + explicit BER_Decoder(const std::vector& vec); - /** - * Set up to BER decode the data in src - */ - explicit BER_Decoder(DataSource& src); + /** + * Set up to BER decode the data in src + */ + explicit BER_Decoder(DataSource& src); - /** - * Set up to BER decode the data in obj - */ - BER_Decoder(const BER_Object& obj) : - BER_Decoder(obj.bits(), obj.length()) {} + /** + * Set up to BER decode the data in obj + */ + BER_Decoder(const BER_Object& obj) : BER_Decoder(obj.bits(), obj.length()) {} - /** - * Set up to BER decode the data in obj - */ - BER_Decoder(BER_Object&& obj) : - BER_Decoder(std::move(obj), nullptr) {} + /** + * Set up to BER decode the data in obj + */ + BER_Decoder(BER_Object&& obj) : BER_Decoder(std::move(obj), nullptr) {} - BER_Decoder(const BER_Decoder& other); + BER_Decoder(const BER_Decoder& other); - BER_Decoder& operator=(const BER_Decoder&) = delete; + BER_Decoder& operator=(const BER_Decoder&) = delete; - /** - * Get the next object in the data stream. - * If EOF, returns an object with type NO_OBJECT. - */ - BER_Object get_next_object(); + /** + * Get the next object in the data stream. + * If EOF, returns an object with type NO_OBJECT. + */ + BER_Object get_next_object(); - BER_Decoder& get_next(BER_Object& ber) - { - ber = get_next_object(); - return (*this); - } + BER_Decoder& get_next(BER_Object& ber) { + ber = get_next_object(); + return (*this); + } - /** - * Push an object back onto the stream. Throws if another - * object was previously pushed and has not been subsequently - * read out. - */ - void push_back(const BER_Object& obj); + /** + * Push an object back onto the stream. Throws if another + * object was previously pushed and has not been subsequently + * read out. + */ + void push_back(const BER_Object& obj); - /** - * Push an object back onto the stream. Throws if another - * object was previously pushed and has not been subsequently - * read out. - */ - void push_back(BER_Object&& obj); + /** + * Push an object back onto the stream. Throws if another + * object was previously pushed and has not been subsequently + * read out. + */ + void push_back(BER_Object&& obj); - /** - * Return true if there is at least one more item remaining - */ - bool more_items() const; + /** + * Return true if there is at least one more item remaining + */ + bool more_items() const; - /** - * Verify the stream is concluded, throws otherwise. - * Returns (*this) - */ - BER_Decoder& verify_end(); + /** + * Verify the stream is concluded, throws otherwise. + * Returns (*this) + */ + BER_Decoder& verify_end(); - /** - * Verify the stream is concluded, throws otherwise. - * Returns (*this) - */ - BER_Decoder& verify_end(const std::string& err_msg); + /** + * Verify the stream is concluded, throws otherwise. + * Returns (*this) + */ + BER_Decoder& verify_end(const std::string& err_msg); - /** - * Discard any data that remains unread - * Returns (*this) - */ - BER_Decoder& discard_remaining(); + /** + * Discard any data that remains unread + * Returns (*this) + */ + BER_Decoder& discard_remaining(); - /** - * Start decoding a constructed data (sequence or set) - */ - BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL); + /** + * Start decoding a constructed data (sequence or set) + */ + BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL); - /** - * Finish decoding a constructed data, throws if any data remains. - * Returns the parent of *this (ie the object on which start_cons was called). - */ - BER_Decoder& end_cons(); + /** + * Finish decoding a constructed data, throws if any data remains. + * Returns the parent of *this (ie the object on which start_cons was called). + */ + BER_Decoder& end_cons(); - /** - * Get next object and copy value to POD type - * Asserts value length is equal to POD type sizeof. - * Asserts Type tag and optional Class tag according to parameters. - * Copy value to POD type (struct, union, C-style array, std::array, etc.). - * @param out POD type reference where to copy object value - * @param type_tag ASN1_Tag enum to assert type on object read - * @param class_tag ASN1_Tag enum to assert class on object read (default: CONTEXT_SPECIFIC) - * @return this reference - */ - template - BER_Decoder& get_next_value(T &out, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC) - { - static_assert(std::is_pod::value, "Type must be POD"); + /** + * Get next object and copy value to POD type + * Asserts value length is equal to POD type sizeof. + * Asserts Type tag and optional Class tag according to parameters. + * Copy value to POD type (struct, union, C-style array, std::array, etc.). + * @param out POD type reference where to copy object value + * @param type_tag ASN1_Tag enum to assert type on object read + * @param class_tag ASN1_Tag enum to assert class on object read (default: CONTEXT_SPECIFIC) + * @return this reference + */ + template + BER_Decoder& get_next_value(T& out, ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC) { + static_assert(std::is_pod::value, "Type must be POD"); - BER_Object obj = get_next_object(); - obj.assert_is_a(type_tag, class_tag); + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, class_tag); - if (obj.length() != sizeof(T)) - throw BER_Decoding_Error( - "Size mismatch. Object value size is " + - std::to_string(obj.length()) + - "; Output type size is " + - std::to_string(sizeof(T))); + if (obj.length() != sizeof(T)) + throw BER_Decoding_Error("Size mismatch. Object value size is " + + std::to_string(obj.length()) + "; Output type size is " + + std::to_string(sizeof(T))); - copy_mem(reinterpret_cast(&out), obj.bits(), obj.length()); + copy_mem(reinterpret_cast(&out), obj.bits(), obj.length()); - return (*this); - } + return (*this); + } - /* - * Save all the bytes remaining in the source - */ - template - BER_Decoder& raw_bytes(std::vector& out) - { - out.clear(); - uint8_t buf; - while(m_source->read_byte(buf)) - out.push_back(buf); - return (*this); - } + /* + * Save all the bytes remaining in the source + */ + template + BER_Decoder& raw_bytes(std::vector& out) { + out.clear(); + uint8_t buf; + while (m_source->read_byte(buf)) out.push_back(buf); + return (*this); + } - BER_Decoder& decode_null(); + BER_Decoder& decode_null(); - /** - * Decode a BER encoded BOOLEAN - */ - BER_Decoder& decode(bool& out) - { - return decode(out, BOOLEAN, UNIVERSAL); - } + /** + * Decode a BER encoded BOOLEAN + */ + BER_Decoder& decode(bool& out) { return decode(out, BOOLEAN, UNIVERSAL); } - /* - * Decode a small BER encoded INTEGER - */ - BER_Decoder& decode(size_t& out) - { - return decode(out, INTEGER, UNIVERSAL); - } + /* + * Decode a small BER encoded INTEGER + */ + BER_Decoder& decode(size_t& out) { return decode(out, INTEGER, UNIVERSAL); } - /* - * Decode a BER encoded INTEGER - */ - BER_Decoder& decode(BigInt& out) - { - return decode(out, INTEGER, UNIVERSAL); - } + /* + * Decode a BER encoded INTEGER + */ + BER_Decoder& decode(BigInt& out) { return decode(out, INTEGER, UNIVERSAL); } - std::vector get_next_octet_string() - { - std::vector out_vec; - decode(out_vec, OCTET_STRING); - return out_vec; - } + std::vector get_next_octet_string() { + std::vector out_vec; + decode(out_vec, OCTET_STRING); + return out_vec; + } - /* - * BER decode a BIT STRING or OCTET STRING - */ - template - BER_Decoder& decode(std::vector& out, ASN1_Tag real_type) - { - return decode(out, real_type, real_type, UNIVERSAL); - } + /* + * BER decode a BIT STRING or OCTET STRING + */ + template + BER_Decoder& decode(std::vector& out, ASN1_Tag real_type) { + return decode(out, real_type, real_type, UNIVERSAL); + } - BER_Decoder& decode(bool& v, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + BER_Decoder& decode(bool& v, ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(size_t& v, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + BER_Decoder& decode(size_t& v, ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(BigInt& v, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + BER_Decoder& decode(BigInt& v, ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(std::vector& v, - ASN1_Tag real_type, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + BER_Decoder& decode(std::vector& v, ASN1_Tag real_type, ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(secure_vector& v, - ASN1_Tag real_type, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + BER_Decoder& decode(secure_vector& v, ASN1_Tag real_type, ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(class ASN1_Object& obj, - ASN1_Tag type_tag = NO_OBJECT, - ASN1_Tag class_tag = NO_OBJECT); + BER_Decoder& decode(class ASN1_Object& obj, ASN1_Tag type_tag = NO_OBJECT, + ASN1_Tag class_tag = NO_OBJECT); - /** - * Decode an integer value which is typed as an octet string - */ - BER_Decoder& decode_octet_string_bigint(BigInt& b); + /** + * Decode an integer value which is typed as an octet string + */ + BER_Decoder& decode_octet_string_bigint(BigInt& b); - uint64_t decode_constrained_integer(ASN1_Tag type_tag, - ASN1_Tag class_tag, - size_t T_bytes); + uint64_t decode_constrained_integer(ASN1_Tag type_tag, ASN1_Tag class_tag, size_t T_bytes); - template BER_Decoder& decode_integer_type(T& out) - { - return decode_integer_type(out, INTEGER, UNIVERSAL); - } + template + BER_Decoder& decode_integer_type(T& out) { + return decode_integer_type(out, INTEGER, UNIVERSAL); + } - template - BER_Decoder& decode_integer_type(T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC) - { - out = static_cast(decode_constrained_integer(type_tag, class_tag, sizeof(out))); - return (*this); - } + template + BER_Decoder& decode_integer_type(T& out, ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC) { + out = static_cast(decode_constrained_integer(type_tag, class_tag, sizeof(out))); + return (*this); + } - template - BER_Decoder& decode_optional(T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag, - const T& default_value = T()); + template + BER_Decoder& decode_optional(T& out, ASN1_Tag type_tag, ASN1_Tag class_tag, + const T& default_value = T()); - template - BER_Decoder& decode_optional_implicit( - T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag, - ASN1_Tag real_type, - ASN1_Tag real_class, - const T& default_value = T()); + template + BER_Decoder& decode_optional_implicit(T& out, ASN1_Tag type_tag, ASN1_Tag class_tag, + ASN1_Tag real_type, ASN1_Tag real_class, + const T& default_value = T()); - template - BER_Decoder& decode_list(std::vector& out, - ASN1_Tag type_tag = SEQUENCE, - ASN1_Tag class_tag = UNIVERSAL); + template + BER_Decoder& decode_list(std::vector& out, ASN1_Tag type_tag = SEQUENCE, + ASN1_Tag class_tag = UNIVERSAL); - template - BER_Decoder& decode_and_check(const T& expected, - const std::string& error_msg) - { - T actual; - decode(actual); + template + BER_Decoder& decode_and_check(const T& expected, const std::string& error_msg) { + T actual; + decode(actual); - if(actual != expected) - throw Decoding_Error(error_msg); + if (actual != expected) throw Decoding_Error(error_msg); - return (*this); - } + return (*this); + } - /* - * Decode an OPTIONAL string type - */ - template - BER_Decoder& decode_optional_string(std::vector& out, - ASN1_Tag real_type, - uint16_t type_no, - ASN1_Tag class_tag = CONTEXT_SPECIFIC) - { - BER_Object obj = get_next_object(); + /* + * Decode an OPTIONAL string type + */ + template + BER_Decoder& decode_optional_string(std::vector& out, ASN1_Tag real_type, + uint16_t type_no, ASN1_Tag class_tag = CONTEXT_SPECIFIC) { + BER_Object obj = get_next_object(); - ASN1_Tag type_tag = static_cast(type_no); + ASN1_Tag type_tag = static_cast(type_no); - if(obj.is_a(type_tag, class_tag)) - { - if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC)) - { - BER_Decoder(std::move(obj)).decode(out, real_type).verify_end(); - } - else - { - push_back(std::move(obj)); - decode(out, real_type, type_tag, class_tag); - } + if (obj.is_a(type_tag, class_tag)) { + if ((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC)) { + BER_Decoder(std::move(obj)).decode(out, real_type).verify_end(); + } else { + push_back(std::move(obj)); + decode(out, real_type, type_tag, class_tag); } - else - { + } else { out.clear(); push_back(std::move(obj)); - } + } - return (*this); - } + return (*this); + } private: - BER_Decoder(BER_Object&& obj, BER_Decoder* parent); + BER_Decoder(BER_Object&& obj, BER_Decoder* parent); - BER_Decoder* m_parent = nullptr; - BER_Object m_pushed; - // either m_data_src.get() or an unowned pointer - DataSource* m_source; - mutable std::unique_ptr m_data_src; - }; + BER_Decoder* m_parent = nullptr; + BER_Object m_pushed; + // either m_data_src.get() or an unowned pointer + DataSource* m_source; + mutable std::unique_ptr m_data_src; +}; /* -* Decode an OPTIONAL or DEFAULT element -*/ -template -BER_Decoder& BER_Decoder::decode_optional(T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag, - const T& default_value) - { - BER_Object obj = get_next_object(); + * Decode an OPTIONAL or DEFAULT element + */ +template +BER_Decoder& BER_Decoder::decode_optional(T& out, ASN1_Tag type_tag, ASN1_Tag class_tag, + const T& default_value) { + BER_Object obj = get_next_object(); - if(obj.is_a(type_tag, class_tag)) - { - if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC)) - { - BER_Decoder(std::move(obj)).decode(out).verify_end(); - } - else - { - push_back(std::move(obj)); - decode(out, type_tag, class_tag); - } - } - else - { - out = default_value; - push_back(std::move(obj)); - } - - return (*this); - } - -/* -* Decode an OPTIONAL or DEFAULT element -*/ -template -BER_Decoder& BER_Decoder::decode_optional_implicit( - T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag, - ASN1_Tag real_type, - ASN1_Tag real_class, - const T& default_value) - { - BER_Object obj = get_next_object(); - - if(obj.is_a(type_tag, class_tag)) - { - obj.set_tagging(real_type, real_class); - push_back(std::move(obj)); - decode(out, real_type, real_class); - } - else - { - // Not what we wanted, push it back on the stream - out = default_value; - push_back(std::move(obj)); - } - - return (*this); - } -/* -* Decode a list of homogenously typed values -*/ -template -BER_Decoder& BER_Decoder::decode_list(std::vector& vec, - ASN1_Tag type_tag, - ASN1_Tag class_tag) - { - BER_Decoder list = start_cons(type_tag, class_tag); - - while(list.more_items()) - { - T value; - list.decode(value); - vec.push_back(std::move(value)); - } - - list.end_cons(); - - return (*this); - } + if (obj.is_a(type_tag, class_tag)) { + if ((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC)) { + BER_Decoder(std::move(obj)).decode(out).verify_end(); + } else { + push_back(std::move(obj)); + decode(out, type_tag, class_tag); + } + } else { + out = default_value; + push_back(std::move(obj)); + } + return (*this); } +/* + * Decode an OPTIONAL or DEFAULT element + */ +template +BER_Decoder& BER_Decoder::decode_optional_implicit(T& out, ASN1_Tag type_tag, ASN1_Tag class_tag, + ASN1_Tag real_type, ASN1_Tag real_class, + const T& default_value) { + BER_Object obj = get_next_object(); + + if (obj.is_a(type_tag, class_tag)) { + obj.set_tagging(real_type, real_class); + push_back(std::move(obj)); + decode(out, real_type, real_class); + } else { + // Not what we wanted, push it back on the stream + out = default_value; + push_back(std::move(obj)); + } + + return (*this); +} +/* + * Decode a list of homogenously typed values + */ +template +BER_Decoder& BER_Decoder::decode_list(std::vector& vec, ASN1_Tag type_tag, ASN1_Tag class_tag) { + BER_Decoder list = start_cons(type_tag, class_tag); + + while (list.more_items()) { + T value; + list.decode(value); + vec.push_back(std::move(value)); + } + + list.end_cons(); + + return (*this); +} + +} // namespace Botan + namespace Botan { class RandomNumberGenerator; /** -* Arbitrary precision integer -*/ -class BOTAN_PUBLIC_API(2,0) BigInt final - { + * Arbitrary precision integer + */ +class BOTAN_PUBLIC_API(2, 0) BigInt final { public: - /** + /** * Base enumerator for encoding and decoding */ - enum Base { Decimal = 10, Hexadecimal = 16, Binary = 256 }; + enum Base { Decimal = 10, Hexadecimal = 16, Binary = 256 }; - /** + /** * Sign symbol definitions for positive and negative numbers */ - enum Sign { Negative = 0, Positive = 1 }; + enum Sign { Negative = 0, Positive = 1 }; - /** + /** * DivideByZero Exception * * In a future release this exception will be removed and its usage * replaced by Invalid_Argument */ - class BOTAN_PUBLIC_API(2,0) DivideByZero final : public Invalid_Argument - { - public: - DivideByZero() : Invalid_Argument("BigInt divide by zero") {} - }; + class BOTAN_PUBLIC_API(2, 0) DivideByZero final : public Invalid_Argument { + public: + DivideByZero() : Invalid_Argument("BigInt divide by zero") {} + }; - /** + /** * Create empty BigInt */ - BigInt() = default; + BigInt() = default; - /** + /** * Create BigInt from 64 bit integer * @param n initial value of this BigInt */ - BigInt(uint64_t n); + BigInt(uint64_t n); - /** + /** * Copy Constructor * @param other the BigInt to copy */ - BigInt(const BigInt& other) = default; + BigInt(const BigInt& other) = default; - /** + /** * Create BigInt from a string. If the string starts with 0x the * rest of the string will be interpreted as hexadecimal digits. * Otherwise, it will be interpreted as a decimal number. * * @param str the string to parse for an integer value */ - explicit BigInt(const std::string& str); + explicit BigInt(const std::string& str); - /** + /** * Create a BigInt from an integer in a byte array * @param buf the byte array holding the value * @param length size of buf */ - BigInt(const uint8_t buf[], size_t length); + BigInt(const uint8_t buf[], size_t length); - /** + /** * Create a BigInt from an integer in a byte array * @param vec the byte vector holding the value */ - template - explicit BigInt(const std::vector& vec) : BigInt(vec.data(), vec.size()) {} + template + explicit BigInt(const std::vector& vec) : BigInt(vec.data(), vec.size()) {} - /** + /** * Create a BigInt from an integer in a byte array * @param buf the byte array holding the value * @param length size of buf * @param base is the number base of the integer in buf */ - BigInt(const uint8_t buf[], size_t length, Base base); + BigInt(const uint8_t buf[], size_t length, Base base); - /** + /** * Create a BigInt from an integer in a byte array * @param buf the byte array holding the value * @param length size of buf * @param max_bits if the resulting integer is more than max_bits, * it will be shifted so it is at most max_bits in length. */ - BigInt(const uint8_t buf[], size_t length, size_t max_bits); + BigInt(const uint8_t buf[], size_t length, size_t max_bits); - /** + /** * Create a BigInt from an array of words * @param words the words * @param length number of words */ - BigInt(const word words[], size_t length); + BigInt(const word words[], size_t length); - /** + /** * \brief Create a random BigInt of the specified size * * @param rng random number generator @@ -3725,214 +3409,202 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * * @see randomize */ - BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit = true); + BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit = true); - /** + /** * Create BigInt of specified size, all zeros * @param sign the sign * @param n size of the internal register in words */ - BigInt(Sign sign, size_t n); + BigInt(Sign sign, size_t n); - /** + /** * Move constructor */ - BigInt(BigInt&& other) - { - this->swap(other); - } + BigInt(BigInt&& other) { this->swap(other); } - /** + /** * Move assignment */ - BigInt& operator=(BigInt&& other) - { - if(this != &other) - this->swap(other); + BigInt& operator=(BigInt&& other) { + if (this != &other) this->swap(other); return (*this); - } + } - /** + /** * Copy assignment */ - BigInt& operator=(const BigInt&) = default; + BigInt& operator=(const BigInt&) = default; - /** + /** * Swap this value with another * @param other BigInt to swap values with */ - void swap(BigInt& other) - { + void swap(BigInt& other) { m_data.swap(other.m_data); std::swap(m_signedness, other.m_signedness); - } + } - void swap_reg(secure_vector& reg) - { + void swap_reg(secure_vector& reg) { m_data.swap(reg); // sign left unchanged - } + } - /** + /** * += operator * @param y the BigInt to add to this */ - BigInt& operator+=(const BigInt& y) - { - return add(y.data(), y.sig_words(), y.sign()); - } + BigInt& operator+=(const BigInt& y) { return add(y.data(), y.sig_words(), y.sign()); } - /** + /** * += operator * @param y the word to add to this */ - BigInt& operator+=(word y) - { - return add(&y, 1, Positive); - } + BigInt& operator+=(word y) { return add(&y, 1, Positive); } - /** + /** * -= operator * @param y the BigInt to subtract from this */ - BigInt& operator-=(const BigInt& y) - { - return sub(y.data(), y.sig_words(), y.sign()); - } + BigInt& operator-=(const BigInt& y) { return sub(y.data(), y.sig_words(), y.sign()); } - /** + /** * -= operator * @param y the word to subtract from this */ - BigInt& operator-=(word y) - { - return sub(&y, 1, Positive); - } + BigInt& operator-=(word y) { return sub(&y, 1, Positive); } - /** + /** * *= operator * @param y the BigInt to multiply with this */ - BigInt& operator*=(const BigInt& y); + BigInt& operator*=(const BigInt& y); - /** + /** * *= operator * @param y the word to multiply with this */ - BigInt& operator*=(word y); + BigInt& operator*=(word y); - /** + /** * /= operator * @param y the BigInt to divide this by */ - BigInt& operator/=(const BigInt& y); + BigInt& operator/=(const BigInt& y); - /** + /** * Modulo operator * @param y the modulus to reduce this by */ - BigInt& operator%=(const BigInt& y); + BigInt& operator%=(const BigInt& y); - /** + /** * Modulo operator * @param y the modulus (word) to reduce this by */ - word operator%=(word y); + word operator%=(word y); - /** + /** * Left shift operator * @param shift the number of bits to shift this left by */ - BigInt& operator<<=(size_t shift); + BigInt& operator<<=(size_t shift); - /** + /** * Right shift operator * @param shift the number of bits to shift this right by */ - BigInt& operator>>=(size_t shift); + BigInt& operator>>=(size_t shift); - /** + /** * Increment operator */ - BigInt& operator++() { return (*this += 1); } + BigInt& operator++() { return (*this += 1); } - /** + /** * Decrement operator */ - BigInt& operator--() { return (*this -= 1); } + BigInt& operator--() { return (*this -= 1); } - /** + /** * Postfix increment operator */ - BigInt operator++(int) { BigInt x = (*this); ++(*this); return x; } + BigInt operator++(int) { + BigInt x = (*this); + ++(*this); + return x; + } - /** + /** * Postfix decrement operator */ - BigInt operator--(int) { BigInt x = (*this); --(*this); return x; } + BigInt operator--(int) { + BigInt x = (*this); + --(*this); + return x; + } - /** + /** * Unary negation operator * @return negative this */ - BigInt operator-() const; + BigInt operator-() const; - /** + /** * ! operator * @return true iff this is zero, otherwise false */ - bool operator !() const { return (!is_nonzero()); } + bool operator!() const { return (!is_nonzero()); } - static BigInt add2(const BigInt& x, const word y[], size_t y_words, Sign y_sign); + static BigInt add2(const BigInt& x, const word y[], size_t y_words, Sign y_sign); - BigInt& add(const word y[], size_t y_words, Sign sign); + BigInt& add(const word y[], size_t y_words, Sign sign); - BigInt& sub(const word y[], size_t y_words, Sign sign) - { + BigInt& sub(const word y[], size_t y_words, Sign sign) { return add(y, y_words, sign == Positive ? Negative : Positive); - } + } - /** + /** * Multiply this with y * @param y the BigInt to multiply with this * @param ws a temp workspace */ - BigInt& mul(const BigInt& y, secure_vector& ws); + BigInt& mul(const BigInt& y, secure_vector& ws); - /** + /** * Square value of *this * @param ws a temp workspace */ - BigInt& square(secure_vector& ws); + BigInt& square(secure_vector& ws); - /** + /** * Set *this to y - *this * @param y the BigInt to subtract from as a sequence of words * @param y_words length of y in words * @param ws a temp workspace */ - BigInt& rev_sub(const word y[], size_t y_words, secure_vector& ws); + BigInt& rev_sub(const word y[], size_t y_words, secure_vector& ws); - /** + /** * Set *this to (*this + y) % mod * This function assumes *this is >= 0 && < mod * @param y the BigInt to add - assumed y >= 0 and y < mod * @param mod the positive modulus * @param ws a temp workspace */ - BigInt& mod_add(const BigInt& y, const BigInt& mod, secure_vector& ws); + BigInt& mod_add(const BigInt& y, const BigInt& mod, secure_vector& ws); - /** + /** * Set *this to (*this - y) % mod * This function assumes *this is >= 0 && < mod * @param y the BigInt to subtract - assumed y >= 0 and y < mod * @param mod the positive modulus * @param ws a temp workspace */ - BigInt& mod_sub(const BigInt& y, const BigInt& mod, secure_vector& ws); + BigInt& mod_sub(const BigInt& y, const BigInt& mod, secure_vector& ws); - /** + /** * Set *this to (*this * y) % mod * This function assumes *this is >= 0 && < mod * y should be small, less than 16 @@ -3940,18 +3612,18 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @param mod the positive modulus * @param ws a temp workspace */ - BigInt& mod_mul(uint8_t y, const BigInt& mod, secure_vector& ws); + BigInt& mod_mul(uint8_t y, const BigInt& mod, secure_vector& ws); - /** + /** * Return *this % mod * * Assumes that *this is (if anything) only slightly larger than * mod and performs repeated subtractions. It should not be used if * *this is much larger than mod, instead use modulo operator. */ - size_t reduce_below(const BigInt& mod, secure_vector &ws); + size_t reduce_below(const BigInt& mod, secure_vector& ws); - /** + /** * Return *this % mod * * Assumes that *this is (if anything) only slightly larger than mod and @@ -3961,82 +3633,79 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * Performs exactly bound subtractions, so if *this is >= bound*mod then the * result will not be fully reduced. If bound is zero, nothing happens. */ - void ct_reduce_below(const BigInt& mod, secure_vector &ws, size_t bound); + void ct_reduce_below(const BigInt& mod, secure_vector& ws, size_t bound); - /** + /** * Zeroize the BigInt. The size of the underlying register is not * modified. */ - void clear() { m_data.set_to_zero(); m_signedness = Positive; } + void clear() { + m_data.set_to_zero(); + m_signedness = Positive; + } - /** + /** * Compare this to another BigInt * @param n the BigInt value to compare with * @param check_signs include sign in comparison? * @result if (thisn) return 1, if both * values are identical return 0 [like Perl's <=> operator] */ - int32_t cmp(const BigInt& n, bool check_signs = true) const; + int32_t cmp(const BigInt& n, bool check_signs = true) const; - /** + /** * Compare this to another BigInt * @param n the BigInt value to compare with * @result true if this == n or false otherwise */ - bool is_equal(const BigInt& n) const; + bool is_equal(const BigInt& n) const; - /** + /** * Compare this to another BigInt * @param n the BigInt value to compare with * @result true if this < n or false otherwise */ - bool is_less_than(const BigInt& n) const; + bool is_less_than(const BigInt& n) const; - /** + /** * Compare this to an integer * @param n the value to compare with * @result if (thisn) return 1, if both * values are identical return 0 [like Perl's <=> operator] */ - int32_t cmp_word(word n) const; + int32_t cmp_word(word n) const; - /** + /** * Test if the integer has an even value * @result true if the integer is even, false otherwise */ - bool is_even() const { return (get_bit(0) == 0); } + bool is_even() const { return (get_bit(0) == 0); } - /** + /** * Test if the integer has an odd value * @result true if the integer is odd, false otherwise */ - bool is_odd() const { return (get_bit(0) == 1); } + bool is_odd() const { return (get_bit(0) == 1); } - /** + /** * Test if the integer is not zero * @result true if the integer is non-zero, false otherwise */ - bool is_nonzero() const { return (!is_zero()); } + bool is_nonzero() const { return (!is_zero()); } - /** + /** * Test if the integer is zero * @result true if the integer is zero, false otherwise */ - bool is_zero() const - { - return (sig_words() == 0); - } + bool is_zero() const { return (sig_words() == 0); } - /** + /** * Set bit at specified position * @param n bit position to set */ - void set_bit(size_t n) - { - conditionally_set_bit(n, true); - } + void set_bit(size_t n) { conditionally_set_bit(n, true); } - /** + /** * Conditionally set bit at specified position. Note if set_it is * false, nothing happens, and if the bit is already set, it * remains set. @@ -4044,213 +3713,187 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @param n bit position to set * @param set_it if the bit should be set */ - void conditionally_set_bit(size_t n, bool set_it); + void conditionally_set_bit(size_t n, bool set_it); - /** + /** * Clear bit at specified position * @param n bit position to clear */ - void clear_bit(size_t n); + void clear_bit(size_t n); - /** + /** * Clear all but the lowest n bits * @param n amount of bits to keep */ - void mask_bits(size_t n) - { - m_data.mask_bits(n); - } + void mask_bits(size_t n) { m_data.mask_bits(n); } - /** + /** * Return bit value at specified position * @param n the bit offset to test * @result true, if the bit at position n is set, false otherwise */ - bool get_bit(size_t n) const - { + bool get_bit(size_t n) const { return ((word_at(n / BOTAN_MP_WORD_BITS) >> (n % BOTAN_MP_WORD_BITS)) & 1); - } + } - /** + /** * Return (a maximum of) 32 bits of the complete value * @param offset the offset to start extracting * @param length amount of bits to extract (starting at offset) * @result the integer extracted from the register starting at * offset with specified length */ - uint32_t get_substring(size_t offset, size_t length) const; + uint32_t get_substring(size_t offset, size_t length) const; - /** + /** * Convert this value into a uint32_t, if it is in the range * [0 ... 2**32-1], or otherwise throw an exception. * @result the value as a uint32_t if conversion is possible */ - uint32_t to_u32bit() const; + uint32_t to_u32bit() const; - /** + /** * Convert this value to a decimal string. * Warning: decimal conversions are relatively slow */ - std::string to_dec_string() const; + std::string to_dec_string() const; - /** + /** * Convert this value to a hexadecimal string. */ - std::string to_hex_string() const; + std::string to_hex_string() const; - /** + /** * @param n the offset to get a byte from * @result byte at offset n */ - uint8_t byte_at(size_t n) const; + uint8_t byte_at(size_t n) const; - /** + /** * Return the word at a specified position of the internal register * @param n position in the register * @return value at position n */ - word word_at(size_t n) const - { - return m_data.get_word_at(n); - } + word word_at(size_t n) const { return m_data.get_word_at(n); } - void set_word_at(size_t i, word w) - { - m_data.set_word_at(i, w); - } + void set_word_at(size_t i, word w) { m_data.set_word_at(i, w); } - void set_words(const word w[], size_t len) - { - m_data.set_words(w, len); - } + void set_words(const word w[], size_t len) { m_data.set_words(w, len); } - /** + /** * Tests if the sign of the integer is negative * @result true, iff the integer has a negative sign */ - bool is_negative() const { return (sign() == Negative); } + bool is_negative() const { return (sign() == Negative); } - /** + /** * Tests if the sign of the integer is positive * @result true, iff the integer has a positive sign */ - bool is_positive() const { return (sign() == Positive); } + bool is_positive() const { return (sign() == Positive); } - /** + /** * Return the sign of the integer * @result the sign of the integer */ - Sign sign() const { return (m_signedness); } + Sign sign() const { return (m_signedness); } - /** + /** * @result the opposite sign of the represented integer value */ - Sign reverse_sign() const - { - if(sign() == Positive) - return Negative; + Sign reverse_sign() const { + if (sign() == Positive) return Negative; return Positive; - } + } - /** + /** * Flip the sign of this BigInt */ - void flip_sign() - { - set_sign(reverse_sign()); - } + void flip_sign() { set_sign(reverse_sign()); } - /** + /** * Set sign of the integer * @param sign new Sign to set */ - void set_sign(Sign sign) - { - if(sign == Negative && is_zero()) - sign = Positive; + void set_sign(Sign sign) { + if (sign == Negative && is_zero()) sign = Positive; m_signedness = sign; - } + } - /** + /** * @result absolute (positive) value of this */ - BigInt abs() const; + BigInt abs() const; - /** + /** * Give size of internal register * @result size of internal register in words */ - size_t size() const { return m_data.size(); } + size_t size() const { return m_data.size(); } - /** + /** * Return how many words we need to hold this value * @result significant words of the represented integer value */ - size_t sig_words() const - { - return m_data.sig_words(); - } + size_t sig_words() const { return m_data.sig_words(); } - /** + /** * Give byte length of the integer * @result byte length of the represented integer value */ - size_t bytes() const; + size_t bytes() const; - /** + /** * Get the bit length of the integer * @result bit length of the represented integer value */ - size_t bits() const; + size_t bits() const; - /** + /** * Get the number of high bits unset in the top (allocated) word * of this integer. Returns BOTAN_MP_WORD_BITS only iff *this is * zero. Ignores sign. */ - size_t top_bits_free() const; + size_t top_bits_free() const; - /** + /** * Return a mutable pointer to the register * @result a pointer to the start of the internal register */ - word* mutable_data() { return m_data.mutable_data(); } + word* mutable_data() { return m_data.mutable_data(); } - /** + /** * Return a const pointer to the register * @result a pointer to the start of the internal register */ - const word* data() const { return m_data.const_data(); } + const word* data() const { return m_data.const_data(); } - /** + /** * Don't use this function in application code */ - secure_vector& get_word_vector() { return m_data.mutable_vector(); } + secure_vector& get_word_vector() { return m_data.mutable_vector(); } - /** + /** * Don't use this function in application code */ - const secure_vector& get_word_vector() const { return m_data.const_vector(); } + const secure_vector& get_word_vector() const { return m_data.const_vector(); } - /** + /** * Increase internal register buffer to at least n words * @param n new size of register */ - void grow_to(size_t n) const { m_data.grow_to(n); } + void grow_to(size_t n) const { m_data.grow_to(n); } - /** + /** * Resize the vector to the minimum word size to hold the integer, or * min_size words, whichever is larger */ - void shrink_to_fit(size_t min_size = 0) - { - m_data.shrink_to_fit(min_size); - } + void shrink_to_fit(size_t min_size = 0) { m_data.shrink_to_fit(min_size); } - void resize(size_t s) { m_data.resize(s); } + void resize(size_t s) { m_data.resize(s); } - /** + /** * Fill BigInt with a random number with size of bitsize * * If \p set_high_bit is true, the highest bit will be set, which causes @@ -4261,15 +3904,15 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @param bitsize number of bits the created random value should have * @param set_high_bit if true, the highest bit is always set */ - void randomize(RandomNumberGenerator& rng, size_t bitsize, bool set_high_bit = true); + void randomize(RandomNumberGenerator& rng, size_t bitsize, bool set_high_bit = true); - /** + /** * Store BigInt-value in a given byte array * @param buf destination byte array for the integer value */ - void binary_encode(uint8_t buf[]) const; + void binary_encode(uint8_t buf[]) const; - /** + /** * Store BigInt-value in a given byte array. If len is less than * the size of the value, then it will be truncated. If len is * greater than the size of the value, it will be zero-padded. @@ -4279,145 +3922,134 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * @param buf destination byte array for the integer value * @param len how many bytes to write */ - void binary_encode(uint8_t buf[], size_t len) const; + void binary_encode(uint8_t buf[], size_t len) const; - /** + /** * Read integer value from a byte array with given size * @param buf byte array buffer containing the integer * @param length size of buf */ - void binary_decode(const uint8_t buf[], size_t length); + void binary_decode(const uint8_t buf[], size_t length); - /** + /** * Read integer value from a byte vector * @param buf the vector to load from */ - template - void binary_decode(const std::vector& buf) - { + template + void binary_decode(const std::vector& buf) { binary_decode(buf.data(), buf.size()); - } + } - /** + /** * @param base the base to measure the size for * @return size of this integer in base base * * Deprecated. This is only needed when using the `encode` and * `encode_locked` functions, which are also deprecated. */ - BOTAN_DEPRECATED("See comments on declaration") - size_t encoded_size(Base base = Binary) const; + BOTAN_DEPRECATED("See comments on declaration") + size_t encoded_size(Base base = Binary) const; - /** + /** * Place the value into out, zero-padding up to size words * Throw if *this cannot be represented in size words */ - void encode_words(word out[], size_t size) const; + void encode_words(word out[], size_t size) const; - /** + /** * If predicate is true assign other to *this * Uses a masked operation to avoid side channels */ - void ct_cond_assign(bool predicate, const BigInt& other); + void ct_cond_assign(bool predicate, const BigInt& other); - /** + /** * If predicate is true swap *this and other * Uses a masked operation to avoid side channels */ - void ct_cond_swap(bool predicate, BigInt& other); + void ct_cond_swap(bool predicate, BigInt& other); - /** + /** * If predicate is true flip the sign of *this */ - void cond_flip_sign(bool predicate); + void cond_flip_sign(bool predicate); #if defined(BOTAN_HAS_VALGRIND) - void const_time_poison() const; - void const_time_unpoison() const; + void const_time_poison() const; + void const_time_unpoison() const; #else - void const_time_poison() const {} - void const_time_unpoison() const {} + void const_time_poison() const {} + void const_time_unpoison() const {} #endif - /** + /** * @param rng a random number generator * @param min the minimum value (must be non-negative) * @param max the maximum value (must be non-negative and > min) * @return random integer in [min,max) */ - static BigInt random_integer(RandomNumberGenerator& rng, - const BigInt& min, - const BigInt& max); + static BigInt random_integer(RandomNumberGenerator& rng, const BigInt& min, const BigInt& max); - /** + /** * Create a power of two * @param n the power of two to create * @return bigint representing 2^n */ - static BigInt power_of_2(size_t n) - { + static BigInt power_of_2(size_t n) { BigInt b; b.set_bit(n); return b; - } + } - /** + /** * Encode the integer value from a BigInt to a std::vector of bytes * @param n the BigInt to use as integer source * @result secure_vector of bytes containing the bytes of the integer */ - static std::vector encode(const BigInt& n) - { + static std::vector encode(const BigInt& n) { std::vector output(n.bytes()); n.binary_encode(output.data()); return output; - } + } - /** + /** * Encode the integer value from a BigInt to a secure_vector of bytes * @param n the BigInt to use as integer source * @result secure_vector of bytes containing the bytes of the integer */ - static secure_vector encode_locked(const BigInt& n) - { + static secure_vector encode_locked(const BigInt& n) { secure_vector output(n.bytes()); n.binary_encode(output.data()); return output; - } + } - /** + /** * Encode the integer value from a BigInt to a byte array * @param buf destination byte array for the encoded integer * @param n the BigInt to use as integer source */ - static BOTAN_DEPRECATED("Use n.binary_encode") void encode(uint8_t buf[], const BigInt& n) - { + static BOTAN_DEPRECATED("Use n.binary_encode") void encode(uint8_t buf[], const BigInt& n) { n.binary_encode(buf); - } + } - /** + /** * Create a BigInt from an integer in a byte array * @param buf the binary value to load * @param length size of buf * @result BigInt representing the integer in the byte array */ - static BigInt decode(const uint8_t buf[], size_t length) - { - return BigInt(buf, length); - } + static BigInt decode(const uint8_t buf[], size_t length) { return BigInt(buf, length); } - /** + /** * Create a BigInt from an integer in a byte array * @param buf the binary value to load * @result BigInt representing the integer in the byte array */ - template - static BigInt decode(const std::vector& buf) - { + template + static BigInt decode(const std::vector& buf) { return BigInt(buf); - } + } - /** + /** * Encode the integer value from a BigInt to a std::vector of bytes * @param n the BigInt to use as integer source * @param base number-base of resulting byte array representation @@ -4427,10 +4059,10 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * take a Base. If you need Hex or Decimal output, use to_hex_string or * to_dec_string resp. */ - BOTAN_DEPRECATED("See comments on declaration") - static std::vector encode(const BigInt& n, Base base); + BOTAN_DEPRECATED("See comments on declaration") + static std::vector encode(const BigInt& n, Base base); - /** + /** * Encode the integer value from a BigInt to a secure_vector of bytes * @param n the BigInt to use as integer source * @param base number-base of resulting byte array representation @@ -4440,11 +4072,10 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * doesn't take a Base. If you need Hex or Decimal output, use to_hex_string * or to_dec_string resp. */ - BOTAN_DEPRECATED("See comments on declaration") - static secure_vector encode_locked(const BigInt& n, - Base base); + BOTAN_DEPRECATED("See comments on declaration") + static secure_vector encode_locked(const BigInt& n, Base base); - /** + /** * Encode the integer value from a BigInt to a byte array * @param buf destination byte array for the encoded integer * value with given base @@ -4454,484 +4085,416 @@ class BOTAN_PUBLIC_API(2,0) BigInt final * Deprecated. If you need Binary, call binary_encode. If you need * Hex or Decimal output, use to_hex_string or to_dec_string resp. */ - BOTAN_DEPRECATED("See comments on declaration") - static void encode(uint8_t buf[], const BigInt& n, Base base); + BOTAN_DEPRECATED("See comments on declaration") + static void encode(uint8_t buf[], const BigInt& n, Base base); - /** + /** * Create a BigInt from an integer in a byte array * @param buf the binary value to load * @param length size of buf * @param base number-base of the integer in buf * @result BigInt representing the integer in the byte array */ - static BigInt decode(const uint8_t buf[], size_t length, - Base base); + static BigInt decode(const uint8_t buf[], size_t length, Base base); - /** + /** * Create a BigInt from an integer in a byte array * @param buf the binary value to load * @param base number-base of the integer in buf * @result BigInt representing the integer in the byte array */ - template - static BigInt decode(const std::vector& buf, Base base) - { - if(base == Binary) - return BigInt(buf); + template + static BigInt decode(const std::vector& buf, Base base) { + if (base == Binary) return BigInt(buf); return BigInt::decode(buf.data(), buf.size(), base); - } + } - /** + /** * Encode a BigInt to a byte array according to IEEE 1363 * @param n the BigInt to encode * @param bytes the length of the resulting secure_vector * @result a secure_vector containing the encoded BigInt */ - static secure_vector encode_1363(const BigInt& n, size_t bytes); + static secure_vector encode_1363(const BigInt& n, size_t bytes); - static void encode_1363(uint8_t out[], size_t bytes, const BigInt& n); + static void encode_1363(uint8_t out[], size_t bytes, const BigInt& n); - /** + /** * Encode two BigInt to a byte array according to IEEE 1363 * @param n1 the first BigInt to encode * @param n2 the second BigInt to encode * @param bytes the length of the encoding of each single BigInt * @result a secure_vector containing the concatenation of the two encoded BigInt */ - static secure_vector encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes); + static secure_vector encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, + size_t bytes); - /** + /** * Set output = vec[idx].m_reg in constant time * * All elements of vec must have the same size, and output must be * pre-allocated with the same size. */ - static void BOTAN_DEPRECATED("No longer in use") const_time_lookup( - secure_vector& output, - const std::vector& vec, - size_t idx); + static void BOTAN_DEPRECATED("No longer in use") + const_time_lookup(secure_vector& output, const std::vector& vec, size_t idx); private: + class Data { + public: + word* mutable_data() { + invalidate_sig_words(); + return m_reg.data(); + } - class Data - { - public: - word* mutable_data() - { - invalidate_sig_words(); - return m_reg.data(); - } + const word* const_data() const { return m_reg.data(); } - const word* const_data() const - { - return m_reg.data(); - } + secure_vector& mutable_vector() { + invalidate_sig_words(); + return m_reg; + } - secure_vector& mutable_vector() - { - invalidate_sig_words(); - return m_reg; - } + const secure_vector& const_vector() const { return m_reg; } - const secure_vector& const_vector() const - { - return m_reg; - } + word get_word_at(size_t n) const { + if (n < m_reg.size()) return m_reg[n]; + return 0; + } - word get_word_at(size_t n) const - { - if(n < m_reg.size()) - return m_reg[n]; - return 0; - } + void set_word_at(size_t i, word w) { + invalidate_sig_words(); + if (i >= m_reg.size()) { + if (w == 0) return; + grow_to(i + 1); + } + m_reg[i] = w; + } - void set_word_at(size_t i, word w) - { - invalidate_sig_words(); - if(i >= m_reg.size()) - { - if(w == 0) - return; - grow_to(i + 1); - } - m_reg[i] = w; - } + void set_words(const word w[], size_t len) { + invalidate_sig_words(); + m_reg.assign(w, w + len); + } - void set_words(const word w[], size_t len) - { - invalidate_sig_words(); - m_reg.assign(w, w + len); - } + void set_to_zero() { + m_reg.resize(m_reg.capacity()); + clear_mem(m_reg.data(), m_reg.size()); + m_sig_words = 0; + } - void set_to_zero() - { - m_reg.resize(m_reg.capacity()); - clear_mem(m_reg.data(), m_reg.size()); - m_sig_words = 0; - } + void set_size(size_t s) { + invalidate_sig_words(); + clear_mem(m_reg.data(), m_reg.size()); + m_reg.resize(s + (8 - (s % 8))); + } - void set_size(size_t s) - { - invalidate_sig_words(); - clear_mem(m_reg.data(), m_reg.size()); - m_reg.resize(s + (8 - (s % 8))); - } + void mask_bits(size_t n) { + if (n == 0) { + return set_to_zero(); + } - void mask_bits(size_t n) - { - if(n == 0) { return set_to_zero(); } + const size_t top_word = n / BOTAN_MP_WORD_BITS; - const size_t top_word = n / BOTAN_MP_WORD_BITS; + // if(top_word < sig_words()) ? + if (top_word < size()) { + const word mask = (static_cast(1) << (n % BOTAN_MP_WORD_BITS)) - 1; + const size_t len = size() - (top_word + 1); + if (len > 0) { + clear_mem(&m_reg[top_word + 1], len); + } + m_reg[top_word] &= mask; + invalidate_sig_words(); + } + } - // if(top_word < sig_words()) ? - if(top_word < size()) - { - const word mask = (static_cast(1) << (n % BOTAN_MP_WORD_BITS)) - 1; - const size_t len = size() - (top_word + 1); - if (len > 0) - { - clear_mem(&m_reg[top_word+1], len); - } - m_reg[top_word] &= mask; - invalidate_sig_words(); - } - } - - void grow_to(size_t n) const - { - if(n > size()) - { - if(n <= m_reg.capacity()) + void grow_to(size_t n) const { + if (n > size()) { + if (n <= m_reg.capacity()) m_reg.resize(n); - else + else m_reg.resize(n + (8 - (n % 8))); - } - } + } + } - size_t size() const { return m_reg.size(); } + size_t size() const { return m_reg.size(); } - void shrink_to_fit(size_t min_size = 0) - { - const size_t words = std::max(min_size, sig_words()); - m_reg.resize(words); - } + void shrink_to_fit(size_t min_size = 0) { + const size_t words = std::max(min_size, sig_words()); + m_reg.resize(words); + } - void resize(size_t s) - { - m_reg.resize(s); - } + void resize(size_t s) { m_reg.resize(s); } - void swap(Data& other) - { - m_reg.swap(other.m_reg); - std::swap(m_sig_words, other.m_sig_words); - } + void swap(Data& other) { + m_reg.swap(other.m_reg); + std::swap(m_sig_words, other.m_sig_words); + } - void swap(secure_vector& reg) - { - m_reg.swap(reg); - invalidate_sig_words(); - } + void swap(secure_vector& reg) { + m_reg.swap(reg); + invalidate_sig_words(); + } - void invalidate_sig_words() const - { - m_sig_words = sig_words_npos; - } + void invalidate_sig_words() const { m_sig_words = sig_words_npos; } - size_t sig_words() const - { - if(m_sig_words == sig_words_npos) - { - m_sig_words = calc_sig_words(); - } - else - { - BOTAN_DEBUG_ASSERT(m_sig_words == calc_sig_words()); - } - return m_sig_words; - } - private: - static const size_t sig_words_npos = static_cast(-1); + size_t sig_words() const { + if (m_sig_words == sig_words_npos) { + m_sig_words = calc_sig_words(); + } else { + BOTAN_DEBUG_ASSERT(m_sig_words == calc_sig_words()); + } + return m_sig_words; + } - size_t calc_sig_words() const; + private: + static const size_t sig_words_npos = static_cast(-1); - mutable secure_vector m_reg; - mutable size_t m_sig_words = sig_words_npos; - }; + size_t calc_sig_words() const; - Data m_data; - Sign m_signedness = Positive; - }; + mutable secure_vector m_reg; + mutable size_t m_sig_words = sig_words_npos; + }; + + Data m_data; + Sign m_signedness = Positive; +}; /* -* Arithmetic Operators -*/ -inline BigInt operator+(const BigInt& x, const BigInt& y) - { - return BigInt::add2(x, y.data(), y.sig_words(), y.sign()); - } - -inline BigInt operator+(const BigInt& x, word y) - { - return BigInt::add2(x, &y, 1, BigInt::Positive); - } - -inline BigInt operator+(word x, const BigInt& y) - { - return y + x; - } - -inline BigInt operator-(const BigInt& x, const BigInt& y) - { - return BigInt::add2(x, y.data(), y.sig_words(), y.reverse_sign()); - } - -inline BigInt operator-(const BigInt& x, word y) - { - return BigInt::add2(x, &y, 1, BigInt::Negative); - } - -BigInt BOTAN_PUBLIC_API(2,0) operator*(const BigInt& x, const BigInt& y); -BigInt BOTAN_PUBLIC_API(2,8) operator*(const BigInt& x, word y); -inline BigInt operator*(word x, const BigInt& y) { return y*x; } - -BigInt BOTAN_PUBLIC_API(2,0) operator/(const BigInt& x, const BigInt& d); -BigInt BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, const BigInt& m); -word BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, word m); -BigInt BOTAN_PUBLIC_API(2,0) operator<<(const BigInt& x, size_t n); -BigInt BOTAN_PUBLIC_API(2,0) operator>>(const BigInt& x, size_t n); - -/* -* Comparison Operators -*/ -inline bool operator==(const BigInt& a, const BigInt& b) - { return a.is_equal(b); } -inline bool operator!=(const BigInt& a, const BigInt& b) - { return !a.is_equal(b); } -inline bool operator<=(const BigInt& a, const BigInt& b) - { return (a.cmp(b) <= 0); } -inline bool operator>=(const BigInt& a, const BigInt& b) - { return (a.cmp(b) >= 0); } -inline bool operator<(const BigInt& a, const BigInt& b) - { return a.is_less_than(b); } -inline bool operator>(const BigInt& a, const BigInt& b) - { return b.is_less_than(a); } - -inline bool operator==(const BigInt& a, word b) - { return (a.cmp_word(b) == 0); } -inline bool operator!=(const BigInt& a, word b) - { return (a.cmp_word(b) != 0); } -inline bool operator<=(const BigInt& a, word b) - { return (a.cmp_word(b) <= 0); } -inline bool operator>=(const BigInt& a, word b) - { return (a.cmp_word(b) >= 0); } -inline bool operator<(const BigInt& a, word b) - { return (a.cmp_word(b) < 0); } -inline bool operator>(const BigInt& a, word b) - { return (a.cmp_word(b) > 0); } - -/* -* I/O Operators -*/ -BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream&, const BigInt&); -BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream&, BigInt&); - + * Arithmetic Operators + */ +inline BigInt operator+(const BigInt& x, const BigInt& y) { + return BigInt::add2(x, y.data(), y.sig_words(), y.sign()); } +inline BigInt operator+(const BigInt& x, word y) { + return BigInt::add2(x, &y, 1, BigInt::Positive); +} + +inline BigInt operator+(word x, const BigInt& y) { return y + x; } + +inline BigInt operator-(const BigInt& x, const BigInt& y) { + return BigInt::add2(x, y.data(), y.sig_words(), y.reverse_sign()); +} + +inline BigInt operator-(const BigInt& x, word y) { + return BigInt::add2(x, &y, 1, BigInt::Negative); +} + +BigInt BOTAN_PUBLIC_API(2, 0) operator*(const BigInt & x, const BigInt & y); +BigInt BOTAN_PUBLIC_API(2, 8) operator*(const BigInt & x, word y); +inline BigInt operator*(word x, const BigInt& y) { return y * x; } + +BigInt BOTAN_PUBLIC_API(2, 0) operator/(const BigInt & x, const BigInt & d); +BigInt BOTAN_PUBLIC_API(2, 0) operator%(const BigInt & x, const BigInt & m); +word BOTAN_PUBLIC_API(2, 0) operator%(const BigInt & x, word m); +BigInt BOTAN_PUBLIC_API(2, 0) operator<<(const BigInt & x, size_t n); +BigInt BOTAN_PUBLIC_API(2, 0) operator>>(const BigInt & x, size_t n); + +/* + * Comparison Operators + */ +inline bool operator==(const BigInt& a, const BigInt& b) { return a.is_equal(b); } +inline bool operator!=(const BigInt& a, const BigInt& b) { return !a.is_equal(b); } +inline bool operator<=(const BigInt& a, const BigInt& b) { return (a.cmp(b) <= 0); } +inline bool operator>=(const BigInt& a, const BigInt& b) { return (a.cmp(b) >= 0); } +inline bool operator<(const BigInt& a, const BigInt& b) { return a.is_less_than(b); } +inline bool operator>(const BigInt& a, const BigInt& b) { return b.is_less_than(a); } + +inline bool operator==(const BigInt& a, word b) { return (a.cmp_word(b) == 0); } +inline bool operator!=(const BigInt& a, word b) { return (a.cmp_word(b) != 0); } +inline bool operator<=(const BigInt& a, word b) { return (a.cmp_word(b) <= 0); } +inline bool operator>=(const BigInt& a, word b) { return (a.cmp_word(b) >= 0); } +inline bool operator<(const BigInt& a, word b) { return (a.cmp_word(b) < 0); } +inline bool operator>(const BigInt& a, word b) { return (a.cmp_word(b) > 0); } + +/* + * I/O Operators + */ +BOTAN_PUBLIC_API(2, 0) std::ostream& operator<<(std::ostream&, const BigInt&); +BOTAN_PUBLIC_API(2, 0) std::istream& operator>>(std::istream&, BigInt&); + +} // namespace Botan + namespace std { -template<> -inline void swap(Botan::BigInt& x, Botan::BigInt& y) - { - x.swap(y); - } - +template <> +inline void swap(Botan::BigInt& x, Botan::BigInt& y) { + x.swap(y); } +} // namespace std + namespace Botan { class RandomNumberGenerator; /** -* Fused multiply-add -* @param a an integer -* @param b an integer -* @param c an integer -* @return (a*b)+c -*/ -BigInt BOTAN_PUBLIC_API(2,0) mul_add(const BigInt& a, - const BigInt& b, - const BigInt& c); + * Fused multiply-add + * @param a an integer + * @param b an integer + * @param c an integer + * @return (a*b)+c + */ +BigInt BOTAN_PUBLIC_API(2, 0) mul_add(const BigInt& a, const BigInt& b, const BigInt& c); /** -* Fused subtract-multiply -* @param a an integer -* @param b an integer -* @param c an integer -* @return (a-b)*c -*/ -BigInt BOTAN_PUBLIC_API(2,0) sub_mul(const BigInt& a, - const BigInt& b, - const BigInt& c); + * Fused subtract-multiply + * @param a an integer + * @param b an integer + * @param c an integer + * @return (a-b)*c + */ +BigInt BOTAN_PUBLIC_API(2, 0) sub_mul(const BigInt& a, const BigInt& b, const BigInt& c); /** -* Fused multiply-subtract -* @param a an integer -* @param b an integer -* @param c an integer -* @return (a*b)-c -*/ -BigInt BOTAN_PUBLIC_API(2,0) mul_sub(const BigInt& a, - const BigInt& b, - const BigInt& c); + * Fused multiply-subtract + * @param a an integer + * @param b an integer + * @param c an integer + * @return (a*b)-c + */ +BigInt BOTAN_PUBLIC_API(2, 0) mul_sub(const BigInt& a, const BigInt& b, const BigInt& c); /** -* Return the absolute value -* @param n an integer -* @return absolute value of n -*/ + * Return the absolute value + * @param n an integer + * @return absolute value of n + */ inline BigInt abs(const BigInt& n) { return n.abs(); } /** -* Compute the greatest common divisor -* @param x a positive integer -* @param y a positive integer -* @return gcd(x,y) -*/ -BigInt BOTAN_PUBLIC_API(2,0) gcd(const BigInt& x, const BigInt& y); + * Compute the greatest common divisor + * @param x a positive integer + * @param y a positive integer + * @return gcd(x,y) + */ +BigInt BOTAN_PUBLIC_API(2, 0) gcd(const BigInt& x, const BigInt& y); /** -* Least common multiple -* @param x a positive integer -* @param y a positive integer -* @return z, smallest integer such that z % x == 0 and z % y == 0 -*/ -BigInt BOTAN_PUBLIC_API(2,0) lcm(const BigInt& x, const BigInt& y); + * Least common multiple + * @param x a positive integer + * @param y a positive integer + * @return z, smallest integer such that z % x == 0 and z % y == 0 + */ +BigInt BOTAN_PUBLIC_API(2, 0) lcm(const BigInt& x, const BigInt& y); /** -* @param x an integer -* @return (x*x) -*/ -BigInt BOTAN_PUBLIC_API(2,0) square(const BigInt& x); + * @param x an integer + * @return (x*x) + */ +BigInt BOTAN_PUBLIC_API(2, 0) square(const BigInt& x); /** -* Modular inversion -* @param x a positive integer -* @param modulus a positive integer -* @return y st (x*y) % modulus == 1 or 0 if no such value -* Not const time -*/ -BigInt BOTAN_PUBLIC_API(2,0) inverse_mod(const BigInt& x, - const BigInt& modulus); + * Modular inversion + * @param x a positive integer + * @param modulus a positive integer + * @return y st (x*y) % modulus == 1 or 0 if no such value + * Not const time + */ +BigInt BOTAN_PUBLIC_API(2, 0) inverse_mod(const BigInt& x, const BigInt& modulus); /** -* Modular inversion using extended binary Euclidian algorithm -* @param x a positive integer -* @param modulus a positive integer -* @return y st (x*y) % modulus == 1 or 0 if no such value -* Not const time -*/ -BigInt BOTAN_PUBLIC_API(2,5) inverse_euclid(const BigInt& x, - const BigInt& modulus); + * Modular inversion using extended binary Euclidian algorithm + * @param x a positive integer + * @param modulus a positive integer + * @return y st (x*y) % modulus == 1 or 0 if no such value + * Not const time + */ +BigInt BOTAN_PUBLIC_API(2, 5) inverse_euclid(const BigInt& x, const BigInt& modulus); /** -* Const time modular inversion -* Requires the modulus be odd -*/ -BigInt BOTAN_PUBLIC_API(2,0) ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod); + * Const time modular inversion + * Requires the modulus be odd + */ +BigInt BOTAN_PUBLIC_API(2, 0) ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod); /** -* Return a^-1 * 2^k mod b -* Returns k, between n and 2n -* Not const time -*/ -size_t BOTAN_PUBLIC_API(2,0) almost_montgomery_inverse(BigInt& result, - const BigInt& a, - const BigInt& b); + * Return a^-1 * 2^k mod b + * Returns k, between n and 2n + * Not const time + */ +size_t BOTAN_PUBLIC_API(2, 0) + almost_montgomery_inverse(BigInt& result, const BigInt& a, const BigInt& b); /** -* Call almost_montgomery_inverse and correct the result to a^-1 mod b -*/ -BigInt BOTAN_PUBLIC_API(2,0) normalized_montgomery_inverse(const BigInt& a, const BigInt& b); - + * Call almost_montgomery_inverse and correct the result to a^-1 mod b + */ +BigInt BOTAN_PUBLIC_API(2, 0) normalized_montgomery_inverse(const BigInt& a, const BigInt& b); /** -* Compute the Jacobi symbol. If n is prime, this is equivalent -* to the Legendre symbol. -* @see http://mathworld.wolfram.com/JacobiSymbol.html -* -* @param a is a non-negative integer -* @param n is an odd integer > 1 -* @return (n / m) -*/ -int32_t BOTAN_PUBLIC_API(2,0) jacobi(const BigInt& a, const BigInt& n); + * Compute the Jacobi symbol. If n is prime, this is equivalent + * to the Legendre symbol. + * @see http://mathworld.wolfram.com/JacobiSymbol.html + * + * @param a is a non-negative integer + * @param n is an odd integer > 1 + * @return (n / m) + */ +int32_t BOTAN_PUBLIC_API(2, 0) jacobi(const BigInt& a, const BigInt& n); /** -* Modular exponentation -* @param b an integer base -* @param x a positive exponent -* @param m a positive modulus -* @return (b^x) % m -*/ -BigInt BOTAN_PUBLIC_API(2,0) power_mod(const BigInt& b, - const BigInt& x, - const BigInt& m); + * Modular exponentation + * @param b an integer base + * @param x a positive exponent + * @param m a positive modulus + * @return (b^x) % m + */ +BigInt BOTAN_PUBLIC_API(2, 0) power_mod(const BigInt& b, const BigInt& x, const BigInt& m); /** -* Compute the square root of x modulo a prime using the -* Shanks-Tonnelli algorithm -* -* @param x the input -* @param p the prime -* @return y such that (y*y)%p == x, or -1 if no such integer -*/ -BigInt BOTAN_PUBLIC_API(2,0) ressol(const BigInt& x, const BigInt& p); + * Compute the square root of x modulo a prime using the + * Shanks-Tonnelli algorithm + * + * @param x the input + * @param p the prime + * @return y such that (y*y)%p == x, or -1 if no such integer + */ +BigInt BOTAN_PUBLIC_API(2, 0) ressol(const BigInt& x, const BigInt& p); /* -* Compute -input^-1 mod 2^MP_WORD_BITS. Throws an exception if input -* is even. If input is odd, then input and 2^n are relatively prime -* and an inverse exists. -*/ -word BOTAN_PUBLIC_API(2,0) monty_inverse(word input); + * Compute -input^-1 mod 2^MP_WORD_BITS. Throws an exception if input + * is even. If input is odd, then input and 2^n are relatively prime + * and an inverse exists. + */ +word BOTAN_PUBLIC_API(2, 0) monty_inverse(word input); /** -* @param x a positive integer -* @return count of the zero bits in x, or, equivalently, the largest -* value of n such that 2^n divides x evenly. Returns zero if -* n is less than or equal to zero. -*/ -size_t BOTAN_PUBLIC_API(2,0) low_zero_bits(const BigInt& x); + * @param x a positive integer + * @return count of the zero bits in x, or, equivalently, the largest + * value of n such that 2^n divides x evenly. Returns zero if + * n is less than or equal to zero. + */ +size_t BOTAN_PUBLIC_API(2, 0) low_zero_bits(const BigInt& x); /** -* Check for primality -* @param n a positive integer to test for primality -* @param rng a random number generator -* @param prob chance of false positive is bounded by 1/2**prob -* @param is_random true if n was randomly chosen by us -* @return true if all primality tests passed, otherwise false -*/ -bool BOTAN_PUBLIC_API(2,0) is_prime(const BigInt& n, - RandomNumberGenerator& rng, - size_t prob = 64, - bool is_random = false); + * Check for primality + * @param n a positive integer to test for primality + * @param rng a random number generator + * @param prob chance of false positive is bounded by 1/2**prob + * @param is_random true if n was randomly chosen by us + * @return true if all primality tests passed, otherwise false + */ +bool BOTAN_PUBLIC_API(2, 0) + is_prime(const BigInt& n, RandomNumberGenerator& rng, size_t prob = 64, bool is_random = false); /** -* Test if the positive integer x is a perfect square ie if there -* exists some positive integer y st y*y == x -* See FIPS 186-4 sec C.4 -* @return 0 if the integer is not a perfect square, otherwise -* returns the positive y st y*y == x -*/ -BigInt BOTAN_PUBLIC_API(2,8) is_perfect_square(const BigInt& x); + * Test if the positive integer x is a perfect square ie if there + * exists some positive integer y st y*y == x + * See FIPS 186-4 sec C.4 + * @return 0 if the integer is not a perfect square, otherwise + * returns the positive y st y*y == x + */ +BigInt BOTAN_PUBLIC_API(2, 8) is_perfect_square(const BigInt& x); -inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng) - { return is_prime(n, rng, 32); } +inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng) { + return is_prime(n, rng, 32); +} -inline bool check_prime(const BigInt& n, RandomNumberGenerator& rng) - { return is_prime(n, rng, 56); } +inline bool check_prime(const BigInt& n, RandomNumberGenerator& rng) { + return is_prime(n, rng, 56); +} -inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng) - { return is_prime(n, rng, 80); } +inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng) { + return is_prime(n, rng, 80); +} /** * Randomly generate a prime suitable for discrete logarithm parameters @@ -4944,50 +4507,43 @@ inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng) * @param prob use test so false positive is bounded by 1/2**prob * @return random prime with the specified criteria */ -BigInt BOTAN_PUBLIC_API(2,0) random_prime(RandomNumberGenerator& rng, - size_t bits, - const BigInt& coprime = 0, - size_t equiv = 1, - size_t equiv_mod = 2, - size_t prob = 128); +BigInt BOTAN_PUBLIC_API(2, 0) + random_prime(RandomNumberGenerator& rng, size_t bits, const BigInt& coprime = 0, + size_t equiv = 1, size_t equiv_mod = 2, size_t prob = 128); /** -* Generate a prime suitable for RSA p/q -* @param keygen_rng a random number generator -* @param prime_test_rng a random number generator -* @param bits how large the resulting prime should be in bits (must be >= 512) -* @param coprime a positive integer that (prime - 1) should be coprime to -* @param prob use test so false positive is bounded by 1/2**prob -* @return random prime with the specified criteria -*/ -BigInt BOTAN_PUBLIC_API(2,7) generate_rsa_prime(RandomNumberGenerator& keygen_rng, - RandomNumberGenerator& prime_test_rng, - size_t bits, - const BigInt& coprime, - size_t prob = 128); + * Generate a prime suitable for RSA p/q + * @param keygen_rng a random number generator + * @param prime_test_rng a random number generator + * @param bits how large the resulting prime should be in bits (must be >= 512) + * @param coprime a positive integer that (prime - 1) should be coprime to + * @param prob use test so false positive is bounded by 1/2**prob + * @return random prime with the specified criteria + */ +BigInt BOTAN_PUBLIC_API(2, 7) + generate_rsa_prime(RandomNumberGenerator& keygen_rng, RandomNumberGenerator& prime_test_rng, + size_t bits, const BigInt& coprime, size_t prob = 128); /** -* Return a 'safe' prime, of the form p=2*q+1 with q prime -* @param rng a random number generator -* @param bits is how long the resulting prime should be -* @return prime randomly chosen from safe primes of length bits -*/ -BigInt BOTAN_PUBLIC_API(2,0) random_safe_prime(RandomNumberGenerator& rng, - size_t bits); + * Return a 'safe' prime, of the form p=2*q+1 with q prime + * @param rng a random number generator + * @param bits is how long the resulting prime should be + * @return prime randomly chosen from safe primes of length bits + */ +BigInt BOTAN_PUBLIC_API(2, 0) random_safe_prime(RandomNumberGenerator& rng, size_t bits); /** -* Generate DSA parameters using the FIPS 186 kosherizer -* @param rng a random number generator -* @param p_out where the prime p will be stored -* @param q_out where the prime q will be stored -* @param pbits how long p will be in bits -* @param qbits how long q will be in bits -* @return random seed used to generate this parameter set -*/ -std::vector BOTAN_PUBLIC_API(2,0) -generate_dsa_primes(RandomNumberGenerator& rng, - BigInt& p_out, BigInt& q_out, - size_t pbits, size_t qbits); + * Generate DSA parameters using the FIPS 186 kosherizer + * @param rng a random number generator + * @param p_out where the prime p will be stored + * @param q_out where the prime q will be stored + * @param pbits how long p will be in bits + * @param qbits how long q will be in bits + * @return random seed used to generate this parameter set + */ +std::vector BOTAN_PUBLIC_API(2, 0) + generate_dsa_primes(RandomNumberGenerator& rng, BigInt& p_out, BigInt& q_out, size_t pbits, + size_t qbits); /** * Generate DSA parameters using the FIPS 186 kosherizer @@ -5001,1654 +4557,1524 @@ generate_dsa_primes(RandomNumberGenerator& rng, * @return true if seed generated a valid DSA parameter set, otherwise false. p_out and q_out are only valid if true was returned. */ -bool BOTAN_PUBLIC_API(2,0) -generate_dsa_primes(RandomNumberGenerator& rng, - BigInt& p_out, BigInt& q_out, - size_t pbits, size_t qbits, - const std::vector& seed, - size_t offset = 0); +bool BOTAN_PUBLIC_API(2, 0) + generate_dsa_primes(RandomNumberGenerator& rng, BigInt& p_out, BigInt& q_out, size_t pbits, + size_t qbits, const std::vector& seed, size_t offset = 0); /** -* The size of the PRIMES[] array -*/ + * The size of the PRIMES[] array + */ const size_t PRIME_TABLE_SIZE = 6541; /** -* A const array of all primes less than 65535 -*/ -extern const uint16_t BOTAN_PUBLIC_API(2,0) PRIMES[]; + * A const array of all primes less than 65535 + */ +extern const uint16_t BOTAN_PUBLIC_API(2, 0) PRIMES[]; -} +} // namespace Botan namespace Botan { /** -* Modular Reducer (using Barrett's technique) -*/ -class BOTAN_PUBLIC_API(2,0) Modular_Reducer - { + * Modular Reducer (using Barrett's technique) + */ +class BOTAN_PUBLIC_API(2, 0) Modular_Reducer { public: - const BigInt& get_modulus() const { return m_modulus; } + const BigInt& get_modulus() const { return m_modulus; } - BigInt reduce(const BigInt& x) const; + BigInt reduce(const BigInt& x) const; - /** - * Multiply mod p - * @param x the first operand - * @param y the second operand - * @return (x * y) % p - */ - BigInt multiply(const BigInt& x, const BigInt& y) const - { return reduce(x * y); } + /** + * Multiply mod p + * @param x the first operand + * @param y the second operand + * @return (x * y) % p + */ + BigInt multiply(const BigInt& x, const BigInt& y) const { return reduce(x * y); } - /** - * Square mod p - * @param x the value to square - * @return (x * x) % p - */ - BigInt square(const BigInt& x) const - { return reduce(Botan::square(x)); } + /** + * Square mod p + * @param x the value to square + * @return (x * x) % p + */ + BigInt square(const BigInt& x) const { return reduce(Botan::square(x)); } - /** - * Cube mod p - * @param x the value to cube - * @return (x * x * x) % p - */ - BigInt cube(const BigInt& x) const - { return multiply(x, this->square(x)); } + /** + * Cube mod p + * @param x the value to cube + * @return (x * x * x) % p + */ + BigInt cube(const BigInt& x) const { return multiply(x, this->square(x)); } - /** - * Low level reduction function. Mostly for internal use. - * Sometimes useful for performance by reducing temporaries - * Reduce x mod p and place the output in out. ** X and out must not reference each other ** - * ws is a temporary workspace. - */ - void reduce(BigInt& out, const BigInt& x, secure_vector& ws) const; + /** + * Low level reduction function. Mostly for internal use. + * Sometimes useful for performance by reducing temporaries + * Reduce x mod p and place the output in out. ** X and out must not reference each other ** + * ws is a temporary workspace. + */ + void reduce(BigInt& out, const BigInt& x, secure_vector& ws) const; - bool initialized() const { return (m_mod_words != 0); } + bool initialized() const { return (m_mod_words != 0); } + + Modular_Reducer() { m_mod_words = 0; } + explicit Modular_Reducer(const BigInt& mod); - Modular_Reducer() { m_mod_words = 0; } - explicit Modular_Reducer(const BigInt& mod); private: - BigInt m_modulus, m_mu; - size_t m_mod_words; - }; + BigInt m_modulus, m_mu; + size_t m_mod_words; +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(blinding.h) +// BOTAN_FUTURE_INTERNAL_HEADER(blinding.h) namespace Botan { class RandomNumberGenerator; /** -* Blinding Function Object. -*/ -class BOTAN_PUBLIC_API(2,0) Blinder final - { + * Blinding Function Object. + */ +class BOTAN_PUBLIC_API(2, 0) Blinder final { public: - /** - * Blind a value. - * The blinding nonce k is freshly generated after - * BOTAN_BLINDING_REINIT_INTERVAL calls to blind(). - * BOTAN_BLINDING_REINIT_INTERVAL = 0 means a fresh - * nonce is only generated once. On every other call, - * an updated nonce is used for blinding: k' = k*k mod n. - * @param x value to blind - * @return blinded value - */ - BigInt blind(const BigInt& x) const; + /** + * Blind a value. + * The blinding nonce k is freshly generated after + * BOTAN_BLINDING_REINIT_INTERVAL calls to blind(). + * BOTAN_BLINDING_REINIT_INTERVAL = 0 means a fresh + * nonce is only generated once. On every other call, + * an updated nonce is used for blinding: k' = k*k mod n. + * @param x value to blind + * @return blinded value + */ + BigInt blind(const BigInt& x) const; - /** - * Unblind a value. - * @param x value to unblind - * @return unblinded value - */ - BigInt unblind(const BigInt& x) const; + /** + * Unblind a value. + * @param x value to unblind + * @return unblinded value + */ + BigInt unblind(const BigInt& x) const; - /** - * @param modulus the modulus - * @param rng the RNG to use for generating the nonce - * @param fwd_func a function that calculates the modular - * exponentiation of the public exponent and the given value (the nonce) - * @param inv_func a function that calculates the modular inverse - * of the given value (the nonce) - */ - Blinder(const BigInt& modulus, - RandomNumberGenerator& rng, - std::function fwd_func, - std::function inv_func); + /** + * @param modulus the modulus + * @param rng the RNG to use for generating the nonce + * @param fwd_func a function that calculates the modular + * exponentiation of the public exponent and the given value (the nonce) + * @param inv_func a function that calculates the modular inverse + * of the given value (the nonce) + */ + Blinder(const BigInt& modulus, RandomNumberGenerator& rng, + std::function fwd_func, + std::function inv_func); - Blinder(const Blinder&) = delete; + Blinder(const Blinder&) = delete; - Blinder& operator=(const Blinder&) = delete; + Blinder& operator=(const Blinder&) = delete; - RandomNumberGenerator& rng() const { return m_rng; } + RandomNumberGenerator& rng() const { return m_rng; } private: - BigInt blinding_nonce() const; + BigInt blinding_nonce() const; - Modular_Reducer m_reducer; - RandomNumberGenerator& m_rng; - std::function m_fwd_fn; - std::function m_inv_fn; - size_t m_modulus_bits = 0; + Modular_Reducer m_reducer; + RandomNumberGenerator& m_rng; + std::function m_fwd_fn; + std::function m_inv_fn; + size_t m_modulus_bits = 0; - mutable BigInt m_e, m_d; - mutable size_t m_counter = 0; - }; + mutable BigInt m_e, m_d; + mutable size_t m_counter = 0; +}; -} +} // namespace Botan #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) - #include +#include #endif -//BOTAN_FUTURE_INTERNAL_HEADER(bswap.h) +// BOTAN_FUTURE_INTERNAL_HEADER(bswap.h) namespace Botan { /** -* Swap a 16 bit integer -*/ -inline uint16_t reverse_bytes(uint16_t val) - { -#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_XLC) - return __builtin_bswap16(val); + * Swap a 16 bit integer + */ +inline uint16_t reverse_bytes(uint16_t val) { +#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || \ + defined(BOTAN_BUILD_COMPILER_IS_XLC) + return __builtin_bswap16(val); #else - return static_cast((val << 8) | (val >> 8)); + return static_cast((val << 8) | (val >> 8)); #endif - } +} /** -* Swap a 32 bit integer -*/ -inline uint32_t reverse_bytes(uint32_t val) - { -#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_XLC) - return __builtin_bswap32(val); + * Swap a 32 bit integer + */ +inline uint32_t reverse_bytes(uint32_t val) { +#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || \ + defined(BOTAN_BUILD_COMPILER_IS_XLC) + return __builtin_bswap32(val); #elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) - return _byteswap_ulong(val); + return _byteswap_ulong(val); #elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - // GCC-style inline assembly for x86 or x86-64 - asm("bswapl %0" : "=r" (val) : "0" (val)); - return val; + // GCC-style inline assembly for x86 or x86-64 + asm("bswapl %0" : "=r"(val) : "0"(val)); + return val; #else - // Generic implementation - uint16_t hi = static_cast(val >> 16); - uint16_t lo = static_cast(val); + // Generic implementation + uint16_t hi = static_cast(val >> 16); + uint16_t lo = static_cast(val); - hi = reverse_bytes(hi); - lo = reverse_bytes(lo); + hi = reverse_bytes(hi); + lo = reverse_bytes(lo); - return (static_cast(lo) << 16) | hi; + return (static_cast(lo) << 16) | hi; #endif - } +} /** -* Swap a 64 bit integer -*/ -inline uint64_t reverse_bytes(uint64_t val) - { -#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_XLC) - return __builtin_bswap64(val); + * Swap a 64 bit integer + */ +inline uint64_t reverse_bytes(uint64_t val) { +#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) || \ + defined(BOTAN_BUILD_COMPILER_IS_XLC) + return __builtin_bswap64(val); #elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) - return _byteswap_uint64(val); + return _byteswap_uint64(val); #elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_ARCH_IS_X86_64) - // GCC-style inline assembly for x86-64 - asm("bswapq %0" : "=r" (val) : "0" (val)); - return val; + // GCC-style inline assembly for x86-64 + asm("bswapq %0" : "=r"(val) : "0"(val)); + return val; #else - /* Generic implementation. Defined in terms of 32-bit bswap so any - * optimizations in that version can help. - */ + /* Generic implementation. Defined in terms of 32-bit bswap so any + * optimizations in that version can help. + */ - uint32_t hi = static_cast(val >> 32); - uint32_t lo = static_cast(val); + uint32_t hi = static_cast(val >> 32); + uint32_t lo = static_cast(val); - hi = reverse_bytes(hi); - lo = reverse_bytes(lo); + hi = reverse_bytes(hi); + lo = reverse_bytes(lo); - return (static_cast(lo) << 32) | hi; + return (static_cast(lo) << 32) | hi; #endif - } +} /** -* Swap 4 Ts in an array -*/ -template -inline void bswap_4(T x[4]) - { - x[0] = reverse_bytes(x[0]); - x[1] = reverse_bytes(x[1]); - x[2] = reverse_bytes(x[2]); - x[3] = reverse_bytes(x[3]); - } - + * Swap 4 Ts in an array + */ +template +inline void bswap_4(T x[4]) { + x[0] = reverse_bytes(x[0]); + x[1] = reverse_bytes(x[1]); + x[2] = reverse_bytes(x[2]); + x[3] = reverse_bytes(x[3]); } +} // namespace Botan + namespace Botan { /** -* This class represents any kind of computation which uses an internal -* state, such as hash functions or MACs -*/ -class BOTAN_PUBLIC_API(2,0) Buffered_Computation - { + * This class represents any kind of computation which uses an internal + * state, such as hash functions or MACs + */ +class BOTAN_PUBLIC_API(2, 0) Buffered_Computation { public: - /** - * @return length of the output of this function in bytes - */ - virtual size_t output_length() const = 0; + /** + * @return length of the output of this function in bytes + */ + virtual size_t output_length() const = 0; - /** - * Add new input to process. - * @param in the input to process as a byte array - * @param length of param in in bytes - */ - void update(const uint8_t in[], size_t length) { add_data(in, length); } + /** + * Add new input to process. + * @param in the input to process as a byte array + * @param length of param in in bytes + */ + void update(const uint8_t in[], size_t length) { add_data(in, length); } - /** - * Add new input to process. - * @param in the input to process as a secure_vector - */ - void update(const secure_vector& in) - { - add_data(in.data(), in.size()); - } + /** + * Add new input to process. + * @param in the input to process as a secure_vector + */ + void update(const secure_vector& in) { add_data(in.data(), in.size()); } - /** - * Add new input to process. - * @param in the input to process as a std::vector - */ - void update(const std::vector& in) - { - add_data(in.data(), in.size()); - } + /** + * Add new input to process. + * @param in the input to process as a std::vector + */ + void update(const std::vector& in) { add_data(in.data(), in.size()); } - void update_be(uint16_t val); - void update_be(uint32_t val); - void update_be(uint64_t val); + void update_be(uint16_t val); + void update_be(uint32_t val); + void update_be(uint64_t val); - void update_le(uint16_t val); - void update_le(uint32_t val); - void update_le(uint64_t val); + void update_le(uint16_t val); + void update_le(uint32_t val); + void update_le(uint64_t val); - /** - * Add new input to process. - * @param str the input to process as a std::string. Will be interpreted - * as a byte array based on the strings encoding. - */ - void update(const std::string& str) - { - add_data(cast_char_ptr_to_uint8(str.data()), str.size()); - } + /** + * Add new input to process. + * @param str the input to process as a std::string. Will be interpreted + * as a byte array based on the strings encoding. + */ + void update(const std::string& str) { + add_data(cast_char_ptr_to_uint8(str.data()), str.size()); + } - /** - * Process a single byte. - * @param in the byte to process - */ - void update(uint8_t in) { add_data(&in, 1); } + /** + * Process a single byte. + * @param in the byte to process + */ + void update(uint8_t in) { add_data(&in, 1); } - /** - * Complete the computation and retrieve the - * final result. - * @param out The byte array to be filled with the result. - * Must be of length output_length() - */ - void final(uint8_t out[]) { final_result(out); } + /** + * Complete the computation and retrieve the + * final result. + * @param out The byte array to be filled with the result. + * Must be of length output_length() + */ + void final(uint8_t out[]) { final_result(out); } - /** - * Complete the computation and retrieve the - * final result. - * @return secure_vector holding the result - */ - secure_vector final() - { - secure_vector output(output_length()); - final_result(output.data()); - return output; - } + /** + * Complete the computation and retrieve the + * final result. + * @return secure_vector holding the result + */ + secure_vector final() { + secure_vector output(output_length()); + final_result(output.data()); + return output; + } - std::vector final_stdvec() - { - std::vector output(output_length()); - final_result(output.data()); - return output; - } + std::vector final_stdvec() { + std::vector output(output_length()); + final_result(output.data()); + return output; + } - template - void final(std::vector& out) - { - out.resize(output_length()); - final_result(out.data()); - } + template + void final(std::vector& out) { + out.resize(output_length()); + final_result(out.data()); + } - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process as a byte array - * @param length the length of the byte array - * @result the result of the call to final() - */ - secure_vector process(const uint8_t in[], size_t length) - { - add_data(in, length); - return final(); - } + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process as a byte array + * @param length the length of the byte array + * @result the result of the call to final() + */ + secure_vector process(const uint8_t in[], size_t length) { + add_data(in, length); + return final(); + } - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process - * @result the result of the call to final() - */ - secure_vector process(const secure_vector& in) - { - add_data(in.data(), in.size()); - return final(); - } + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process + * @result the result of the call to final() + */ + secure_vector process(const secure_vector& in) { + add_data(in.data(), in.size()); + return final(); + } - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process - * @result the result of the call to final() - */ - secure_vector process(const std::vector& in) - { - add_data(in.data(), in.size()); - return final(); - } + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process + * @result the result of the call to final() + */ + secure_vector process(const std::vector& in) { + add_data(in.data(), in.size()); + return final(); + } - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process as a string - * @result the result of the call to final() - */ - secure_vector process(const std::string& in) - { - update(in); - return final(); - } + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process as a string + * @result the result of the call to final() + */ + secure_vector process(const std::string& in) { + update(in); + return final(); + } + + virtual ~Buffered_Computation() = default; - virtual ~Buffered_Computation() = default; private: - /** - * Add more data to the computation - * @param input is an input buffer - * @param length is the length of input in bytes - */ - virtual void add_data(const uint8_t input[], size_t length) = 0; + /** + * Add more data to the computation + * @param input is an input buffer + * @param length is the length of input in bytes + */ + virtual void add_data(const uint8_t input[], size_t length) = 0; - /** - * Write the final output to out - * @param out is an output buffer of output_length() - */ - virtual void final_result(uint8_t out[]) = 0; - }; + /** + * Write the final output to out + * @param out is an output buffer of output_length() + */ + virtual void final_result(uint8_t out[]) = 0; +}; -} +} // namespace Botan namespace Botan { /** -* Struct representing a particular date and time -*/ -class BOTAN_PUBLIC_API(2,0) calendar_point - { + * Struct representing a particular date and time + */ +class BOTAN_PUBLIC_API(2, 0) calendar_point { public: + /** The year */ + uint32_t get_year() const { return year; } - /** The year */ - uint32_t get_year() const { return year; } + /** The month, 1 through 12 for Jan to Dec */ + uint32_t get_month() const { return month; } - /** The month, 1 through 12 for Jan to Dec */ - uint32_t get_month() const { return month; } + /** The day of the month, 1 through 31 (or 28 or 30 based on month */ + uint32_t get_day() const { return day; } - /** The day of the month, 1 through 31 (or 28 or 30 based on month */ - uint32_t get_day() const { return day; } + /** Hour in 24-hour form, 0 to 23 */ + uint32_t get_hour() const { return hour; } - /** Hour in 24-hour form, 0 to 23 */ - uint32_t get_hour() const { return hour; } + /** Minutes in the hour, 0 to 60 */ + uint32_t get_minutes() const { return minutes; } - /** Minutes in the hour, 0 to 60 */ - uint32_t get_minutes() const { return minutes; } + /** Seconds in the minute, 0 to 60, but might be slightly + larger to deal with leap seconds on some systems + */ + uint32_t get_seconds() const { return seconds; } - /** Seconds in the minute, 0 to 60, but might be slightly - larger to deal with leap seconds on some systems - */ - uint32_t get_seconds() const { return seconds; } + /** + * Initialize a calendar_point + * @param y the year + * @param mon the month + * @param d the day + * @param h the hour + * @param min the minute + * @param sec the second + */ + calendar_point(uint32_t y, uint32_t mon, uint32_t d, uint32_t h, uint32_t min, uint32_t sec) + : year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {} - /** - * Initialize a calendar_point - * @param y the year - * @param mon the month - * @param d the day - * @param h the hour - * @param min the minute - * @param sec the second - */ - calendar_point(uint32_t y, uint32_t mon, uint32_t d, uint32_t h, uint32_t min, uint32_t sec) : - year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {} + /** + * Returns an STL timepoint object + */ + std::chrono::system_clock::time_point to_std_timepoint() const; - /** - * Returns an STL timepoint object - */ - std::chrono::system_clock::time_point to_std_timepoint() const; + /** + * Returns a human readable string of the struct's components. + * Formatting might change over time. Currently it is RFC339 'iso-date-time'. + */ + std::string to_string() const; - /** - * Returns a human readable string of the struct's components. - * Formatting might change over time. Currently it is RFC339 'iso-date-time'. - */ - std::string to_string() const; - - BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES: - /* - The member variables are public for historical reasons. Use the get_xxx() functions - defined above. These members will be made private in a future major release. - */ - uint32_t year; - uint32_t month; - uint32_t day; - uint32_t hour; - uint32_t minutes; - uint32_t seconds; - }; + BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES : + /* + The member variables are public for historical reasons. Use the get_xxx() functions + defined above. These members will be made private in a future major release. + */ + uint32_t year; + uint32_t month; + uint32_t day; + uint32_t hour; + uint32_t minutes; + uint32_t seconds; +}; /** -* Convert a time_point to a calendar_point -* @param time_point a time point from the system clock -* @return calendar_point object representing this time point -*/ -BOTAN_PUBLIC_API(2,0) calendar_point calendar_value( - const std::chrono::system_clock::time_point& time_point); + * Convert a time_point to a calendar_point + * @param time_point a time point from the system clock + * @return calendar_point object representing this time point + */ +BOTAN_PUBLIC_API(2, 0) +calendar_point calendar_value(const std::chrono::system_clock::time_point& time_point); -} +} // namespace Botan namespace Botan { /** -* The two possible directions for cipher filters, determining whether they -* actually perform encryption or decryption. -*/ + * The two possible directions for cipher filters, determining whether they + * actually perform encryption or decryption. + */ enum Cipher_Dir : int { ENCRYPTION, DECRYPTION }; /** -* Interface for cipher modes -*/ -class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm - { + * Interface for cipher modes + */ +class BOTAN_PUBLIC_API(2, 0) Cipher_Mode : public SymmetricAlgorithm { public: - /** - * @return list of available providers for this algorithm, empty if not available - * @param algo_spec algorithm name - */ - static std::vector providers(const std::string& algo_spec); + /** + * @return list of available providers for this algorithm, empty if not available + * @param algo_spec algorithm name + */ + static std::vector providers(const std::string& algo_spec); - /** - * Create an AEAD mode - * @param algo the algorithm to create - * @param direction specify if this should be an encryption or decryption AEAD - * @param provider optional specification for provider to use - * @return an AEAD mode or a null pointer if not available - */ - static std::unique_ptr create(const std::string& algo, - Cipher_Dir direction, - const std::string& provider = ""); + /** + * Create an AEAD mode + * @param algo the algorithm to create + * @param direction specify if this should be an encryption or decryption AEAD + * @param provider optional specification for provider to use + * @return an AEAD mode or a null pointer if not available + */ + static std::unique_ptr create(const std::string& algo, Cipher_Dir direction, + const std::string& provider = ""); - /** - * Create an AEAD mode, or throw - * @param algo the algorithm to create - * @param direction specify if this should be an encryption or decryption AEAD - * @param provider optional specification for provider to use - * @return an AEAD mode, or throw an exception - */ - static std::unique_ptr create_or_throw(const std::string& algo, - Cipher_Dir direction, - const std::string& provider = ""); + /** + * Create an AEAD mode, or throw + * @param algo the algorithm to create + * @param direction specify if this should be an encryption or decryption AEAD + * @param provider optional specification for provider to use + * @return an AEAD mode, or throw an exception + */ + static std::unique_ptr create_or_throw(const std::string& algo, + Cipher_Dir direction, + const std::string& provider = ""); - /* - * Prepare for processing a message under the specified nonce - */ - virtual void start_msg(const uint8_t nonce[], size_t nonce_len) = 0; + /* + * Prepare for processing a message under the specified nonce + */ + virtual void start_msg(const uint8_t nonce[], size_t nonce_len) = 0; - /** - * Begin processing a message. - * @param nonce the per message nonce - */ - template - void start(const std::vector& nonce) - { - start_msg(nonce.data(), nonce.size()); - } + /** + * Begin processing a message. + * @param nonce the per message nonce + */ + template + void start(const std::vector& nonce) { + start_msg(nonce.data(), nonce.size()); + } - /** - * Begin processing a message. - * @param nonce the per message nonce - * @param nonce_len length of nonce - */ - void start(const uint8_t nonce[], size_t nonce_len) - { - start_msg(nonce, nonce_len); - } + /** + * Begin processing a message. + * @param nonce the per message nonce + * @param nonce_len length of nonce + */ + void start(const uint8_t nonce[], size_t nonce_len) { start_msg(nonce, nonce_len); } - /** - * Begin processing a message. - */ - void start() - { - return start_msg(nullptr, 0); - } + /** + * Begin processing a message. + */ + void start() { return start_msg(nullptr, 0); } - /** - * Process message blocks - * - * Input must be a multiple of update_granularity - * - * Processes msg in place and returns bytes written. Normally - * this will be either msg_len (indicating the entire message was - * processed) or for certain AEAD modes zero (indicating that the - * mode requires the entire message be processed in one pass). - * - * @param msg the message to be processed - * @param msg_len length of the message in bytes - */ - virtual size_t process(uint8_t msg[], size_t msg_len) = 0; + /** + * Process message blocks + * + * Input must be a multiple of update_granularity + * + * Processes msg in place and returns bytes written. Normally + * this will be either msg_len (indicating the entire message was + * processed) or for certain AEAD modes zero (indicating that the + * mode requires the entire message be processed in one pass). + * + * @param msg the message to be processed + * @param msg_len length of the message in bytes + */ + virtual size_t process(uint8_t msg[], size_t msg_len) = 0; - /** - * Process some data. Input must be in size update_granularity() uint8_t blocks. - * @param buffer in/out parameter which will possibly be resized - * @param offset an offset into blocks to begin processing - */ - void update(secure_vector& buffer, size_t offset = 0) - { - BOTAN_ASSERT(buffer.size() >= offset, "Offset ok"); - uint8_t* buf = buffer.data() + offset; - const size_t buf_size = buffer.size() - offset; + /** + * Process some data. Input must be in size update_granularity() uint8_t blocks. + * @param buffer in/out parameter which will possibly be resized + * @param offset an offset into blocks to begin processing + */ + void update(secure_vector& buffer, size_t offset = 0) { + BOTAN_ASSERT(buffer.size() >= offset, "Offset ok"); + uint8_t* buf = buffer.data() + offset; + const size_t buf_size = buffer.size() - offset; - const size_t written = process(buf, buf_size); - buffer.resize(offset + written); - } + const size_t written = process(buf, buf_size); + buffer.resize(offset + written); + } - /** - * Complete processing of a message. - * - * @param final_block in/out parameter which must be at least - * minimum_final_size() bytes, and will be set to any final output - * @param offset an offset into final_block to begin processing - */ - virtual void finish(secure_vector& final_block, size_t offset = 0) = 0; + /** + * Complete processing of a message. + * + * @param final_block in/out parameter which must be at least + * minimum_final_size() bytes, and will be set to any final output + * @param offset an offset into final_block to begin processing + */ + virtual void finish(secure_vector& final_block, size_t offset = 0) = 0; - /** - * Returns the size of the output if this transform is used to process a - * message with input_length bytes. In most cases the answer is precise. - * If it is not possible to precise (namely for CBC decryption) instead a - * lower bound is returned. - */ - virtual size_t output_length(size_t input_length) const = 0; + /** + * Returns the size of the output if this transform is used to process a + * message with input_length bytes. In most cases the answer is precise. + * If it is not possible to precise (namely for CBC decryption) instead a + * lower bound is returned. + */ + virtual size_t output_length(size_t input_length) const = 0; - /** - * @return size of required blocks to update - */ - virtual size_t update_granularity() const = 0; + /** + * @return size of required blocks to update + */ + virtual size_t update_granularity() const = 0; - /** - * @return required minimium size to finalize() - may be any - * length larger than this. - */ - virtual size_t minimum_final_size() const = 0; + /** + * @return required minimium size to finalize() - may be any + * length larger than this. + */ + virtual size_t minimum_final_size() const = 0; - /** - * @return the default size for a nonce - */ - virtual size_t default_nonce_length() const = 0; + /** + * @return the default size for a nonce + */ + virtual size_t default_nonce_length() const = 0; - /** - * @return true iff nonce_len is a valid length for the nonce - */ - virtual bool valid_nonce_length(size_t nonce_len) const = 0; + /** + * @return true iff nonce_len is a valid length for the nonce + */ + virtual bool valid_nonce_length(size_t nonce_len) const = 0; - /** - * Resets just the message specific state and allows encrypting again under the existing key - */ - virtual void reset() = 0; + /** + * Resets just the message specific state and allows encrypting again under the existing key + */ + virtual void reset() = 0; - /** - * @return true iff this mode provides authentication as well as - * confidentiality. - */ - virtual bool authenticated() const { return false; } + /** + * @return true iff this mode provides authentication as well as + * confidentiality. + */ + virtual bool authenticated() const { return false; } - /** - * @return the size of the authentication tag used (in bytes) - */ - virtual size_t tag_size() const { return 0; } + /** + * @return the size of the authentication tag used (in bytes) + */ + virtual size_t tag_size() const { return 0; } - /** - * @return provider information about this implementation. Default is "base", - * might also return "sse2", "avx2", "openssl", or some other arbitrary string. - */ - virtual std::string provider() const { return "base"; } - }; + /** + * @return provider information about this implementation. Default is "base", + * might also return "sse2", "avx2", "openssl", or some other arbitrary string. + */ + virtual std::string provider() const { return "base"; } +}; /** -* Get a cipher mode by name (eg "AES-128/CBC" or "Serpent/XTS") -* @param algo_spec cipher name -* @param direction ENCRYPTION or DECRYPTION -* @param provider provider implementation to choose -*/ -inline Cipher_Mode* get_cipher_mode(const std::string& algo_spec, - Cipher_Dir direction, - const std::string& provider = "") - { - return Cipher_Mode::create(algo_spec, direction, provider).release(); - } - + * Get a cipher mode by name (eg "AES-128/CBC" or "Serpent/XTS") + * @param algo_spec cipher name + * @param direction ENCRYPTION or DECRYPTION + * @param provider provider implementation to choose + */ +inline Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction, + const std::string& provider = "") { + return Cipher_Mode::create(algo_spec, direction, provider).release(); } -//BOTAN_FUTURE_INTERNAL_HEADER(mode_pad.h) +} // namespace Botan + +// BOTAN_FUTURE_INTERNAL_HEADER(mode_pad.h) namespace Botan { /** -* Block Cipher Mode Padding Method -* This class is pretty limited, it cannot deal well with -* randomized padding methods, or any padding method that -* wants to add more than one block. For instance, it should -* be possible to define cipher text stealing mode as simply -* a padding mode for CBC, which happens to consume the last -* two block (and requires use of the block cipher). -*/ -class BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod - { + * Block Cipher Mode Padding Method + * This class is pretty limited, it cannot deal well with + * randomized padding methods, or any padding method that + * wants to add more than one block. For instance, it should + * be possible to define cipher text stealing mode as simply + * a padding mode for CBC, which happens to consume the last + * two block (and requires use of the block cipher). + */ +class BOTAN_PUBLIC_API(2, 0) BlockCipherModePaddingMethod { public: - /** - * Add padding bytes to buffer. - * @param buffer data to pad - * @param final_block_bytes size of the final block in bytes - * @param block_size size of each block in bytes - */ - virtual void add_padding(secure_vector& buffer, - size_t final_block_bytes, - size_t block_size) const = 0; + /** + * Add padding bytes to buffer. + * @param buffer data to pad + * @param final_block_bytes size of the final block in bytes + * @param block_size size of each block in bytes + */ + virtual void add_padding(secure_vector& buffer, size_t final_block_bytes, + size_t block_size) const = 0; - /** - * Remove padding bytes from block - * @param block the last block - * @param len the size of the block in bytes - * @return number of data bytes, or if the padding is invalid returns len - */ - virtual size_t unpad(const uint8_t block[], size_t len) const = 0; + /** + * Remove padding bytes from block + * @param block the last block + * @param len the size of the block in bytes + * @return number of data bytes, or if the padding is invalid returns len + */ + virtual size_t unpad(const uint8_t block[], size_t len) const = 0; - /** - * @param block_size of the cipher - * @return valid block size for this padding mode - */ - virtual bool valid_blocksize(size_t block_size) const = 0; + /** + * @param block_size of the cipher + * @return valid block size for this padding mode + */ + virtual bool valid_blocksize(size_t block_size) const = 0; - /** - * @return name of the mode - */ - virtual std::string name() const = 0; + /** + * @return name of the mode + */ + virtual std::string name() const = 0; - /** - * virtual destructor - */ - virtual ~BlockCipherModePaddingMethod() = default; - }; + /** + * virtual destructor + */ + virtual ~BlockCipherModePaddingMethod() = default; +}; /** -* PKCS#7 Padding -*/ -class BOTAN_PUBLIC_API(2,0) PKCS7_Padding final : public BlockCipherModePaddingMethod - { + * PKCS#7 Padding + */ +class BOTAN_PUBLIC_API(2, 0) PKCS7_Padding final : public BlockCipherModePaddingMethod { public: - void add_padding(secure_vector& buffer, - size_t final_block_bytes, - size_t block_size) const override; + void add_padding(secure_vector& buffer, size_t final_block_bytes, + size_t block_size) const override; - size_t unpad(const uint8_t[], size_t) const override; + size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } - std::string name() const override { return "PKCS7"; } - }; + std::string name() const override { return "PKCS7"; } +}; /** -* ANSI X9.23 Padding -*/ -class BOTAN_PUBLIC_API(2,0) ANSI_X923_Padding final : public BlockCipherModePaddingMethod - { + * ANSI X9.23 Padding + */ +class BOTAN_PUBLIC_API(2, 0) ANSI_X923_Padding final : public BlockCipherModePaddingMethod { public: - void add_padding(secure_vector& buffer, - size_t final_block_bytes, - size_t block_size) const override; + void add_padding(secure_vector& buffer, size_t final_block_bytes, + size_t block_size) const override; - size_t unpad(const uint8_t[], size_t) const override; + size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } - std::string name() const override { return "X9.23"; } - }; + std::string name() const override { return "X9.23"; } +}; /** -* One And Zeros Padding (ISO/IEC 9797-1, padding method 2) -*/ -class BOTAN_PUBLIC_API(2,0) OneAndZeros_Padding final : public BlockCipherModePaddingMethod - { + * One And Zeros Padding (ISO/IEC 9797-1, padding method 2) + */ +class BOTAN_PUBLIC_API(2, 0) OneAndZeros_Padding final : public BlockCipherModePaddingMethod { public: - void add_padding(secure_vector& buffer, - size_t final_block_bytes, - size_t block_size) const override; + void add_padding(secure_vector& buffer, size_t final_block_bytes, + size_t block_size) const override; - size_t unpad(const uint8_t[], size_t) const override; + size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 2); } + bool valid_blocksize(size_t bs) const override { return (bs > 2); } - std::string name() const override { return "OneAndZeros"; } - }; + std::string name() const override { return "OneAndZeros"; } +}; /** -* ESP Padding (RFC 4304) -*/ -class BOTAN_PUBLIC_API(2,0) ESP_Padding final : public BlockCipherModePaddingMethod - { + * ESP Padding (RFC 4304) + */ +class BOTAN_PUBLIC_API(2, 0) ESP_Padding final : public BlockCipherModePaddingMethod { public: - void add_padding(secure_vector& buffer, - size_t final_block_bytes, - size_t block_size) const override; + void add_padding(secure_vector& buffer, size_t final_block_bytes, + size_t block_size) const override; - size_t unpad(const uint8_t[], size_t) const override; + size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } - std::string name() const override { return "ESP"; } - }; + std::string name() const override { return "ESP"; } +}; /** -* Null Padding -*/ -class BOTAN_PUBLIC_API(2,0) Null_Padding final : public BlockCipherModePaddingMethod - { + * Null Padding + */ +class BOTAN_PUBLIC_API(2, 0) Null_Padding final : public BlockCipherModePaddingMethod { public: - void add_padding(secure_vector&, size_t, size_t) const override - { - /* no padding */ - } + void add_padding(secure_vector&, size_t, size_t) const override { /* no padding */ } - size_t unpad(const uint8_t[], size_t size) const override { return size; } + size_t unpad(const uint8_t[], size_t size) const override { return size; } - bool valid_blocksize(size_t) const override { return true; } + bool valid_blocksize(size_t) const override { return true; } - std::string name() const override { return "NoPadding"; } - }; + std::string name() const override { return "NoPadding"; } +}; /** -* Get a block cipher padding mode by name (eg "NoPadding" or "PKCS7") -* @param algo_spec block cipher padding mode name -*/ -BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec); + * Get a block cipher padding mode by name (eg "NoPadding" or "PKCS7") + * @param algo_spec block cipher padding mode name + */ +BOTAN_PUBLIC_API(2, 0) BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec); -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(cbc.h) +// BOTAN_FUTURE_INTERNAL_HEADER(cbc.h) namespace Botan { /** -* CBC Mode -*/ -class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode - { + * CBC Mode + */ +class BOTAN_PUBLIC_API(2, 0) CBC_Mode : public Cipher_Mode { public: - std::string name() const override; + std::string name() const override; - size_t update_granularity() const override; + size_t update_granularity() const override; - Key_Length_Specification key_spec() const override; + Key_Length_Specification key_spec() const override; - size_t default_nonce_length() const override; + size_t default_nonce_length() const override; - bool valid_nonce_length(size_t n) const override; + bool valid_nonce_length(size_t n) const override; - void clear() override; + void clear() override; - void reset() override; + void reset() override; protected: - CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding); + CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding); - const BlockCipher& cipher() const { return *m_cipher; } + const BlockCipher& cipher() const { return *m_cipher; } - const BlockCipherModePaddingMethod& padding() const - { - BOTAN_ASSERT_NONNULL(m_padding); - return *m_padding; - } + const BlockCipherModePaddingMethod& padding() const { + BOTAN_ASSERT_NONNULL(m_padding); + return *m_padding; + } - size_t block_size() const { return m_block_size; } + size_t block_size() const { return m_block_size; } - secure_vector& state() { return m_state; } + secure_vector& state() { return m_state; } - uint8_t* state_ptr() { return m_state.data(); } + uint8_t* state_ptr() { return m_state.data(); } private: - void start_msg(const uint8_t nonce[], size_t nonce_len) override; + void start_msg(const uint8_t nonce[], size_t nonce_len) override; - void key_schedule(const uint8_t key[], size_t length) override; + void key_schedule(const uint8_t key[], size_t length) override; - std::unique_ptr m_cipher; - std::unique_ptr m_padding; - secure_vector m_state; - size_t m_block_size; - }; + std::unique_ptr m_cipher; + std::unique_ptr m_padding; + secure_vector m_state; + size_t m_block_size; +}; /** -* CBC Encryption -*/ -class BOTAN_PUBLIC_API(2,0) CBC_Encryption : public CBC_Mode - { + * CBC Encryption + */ +class BOTAN_PUBLIC_API(2, 0) CBC_Encryption : public CBC_Mode { public: - /** - * @param cipher block cipher to use - * @param padding padding method to use - */ - CBC_Encryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : - CBC_Mode(cipher, padding) {} + /** + * @param cipher block cipher to use + * @param padding padding method to use + */ + CBC_Encryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) + : CBC_Mode(cipher, padding) {} - size_t process(uint8_t buf[], size_t size) override; + size_t process(uint8_t buf[], size_t size) override; - void finish(secure_vector& final_block, size_t offset = 0) override; + void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override; + size_t output_length(size_t input_length) const override; - size_t minimum_final_size() const override; - }; + size_t minimum_final_size() const override; +}; /** -* CBC Encryption with ciphertext stealing (CBC-CS3 variant) -*/ -class BOTAN_PUBLIC_API(2,0) CTS_Encryption final : public CBC_Encryption - { + * CBC Encryption with ciphertext stealing (CBC-CS3 variant) + */ +class BOTAN_PUBLIC_API(2, 0) CTS_Encryption final : public CBC_Encryption { public: - /** - * @param cipher block cipher to use - */ - explicit CTS_Encryption(BlockCipher* cipher) : CBC_Encryption(cipher, nullptr) {} + /** + * @param cipher block cipher to use + */ + explicit CTS_Encryption(BlockCipher* cipher) : CBC_Encryption(cipher, nullptr) {} - size_t output_length(size_t input_length) const override; + size_t output_length(size_t input_length) const override; - void finish(secure_vector& final_block, size_t offset = 0) override; + void finish(secure_vector& final_block, size_t offset = 0) override; - size_t minimum_final_size() const override; + size_t minimum_final_size() const override; - bool valid_nonce_length(size_t n) const override; - }; + bool valid_nonce_length(size_t n) const override; +}; /** -* CBC Decryption -*/ -class BOTAN_PUBLIC_API(2,0) CBC_Decryption : public CBC_Mode - { + * CBC Decryption + */ +class BOTAN_PUBLIC_API(2, 0) CBC_Decryption : public CBC_Mode { public: - /** - * @param cipher block cipher to use - * @param padding padding method to use - */ - CBC_Decryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : - CBC_Mode(cipher, padding), m_tempbuf(update_granularity()) {} + /** + * @param cipher block cipher to use + * @param padding padding method to use + */ + CBC_Decryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) + : CBC_Mode(cipher, padding), m_tempbuf(update_granularity()) {} - size_t process(uint8_t buf[], size_t size) override; + size_t process(uint8_t buf[], size_t size) override; - void finish(secure_vector& final_block, size_t offset = 0) override; + void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override; + size_t output_length(size_t input_length) const override; - size_t minimum_final_size() const override; + size_t minimum_final_size() const override; - void reset() override; + void reset() override; private: - secure_vector m_tempbuf; - }; + secure_vector m_tempbuf; +}; /** -* CBC Decryption with ciphertext stealing (CBC-CS3 variant) -*/ -class BOTAN_PUBLIC_API(2,0) CTS_Decryption final : public CBC_Decryption - { + * CBC Decryption with ciphertext stealing (CBC-CS3 variant) + */ +class BOTAN_PUBLIC_API(2, 0) CTS_Decryption final : public CBC_Decryption { public: - /** - * @param cipher block cipher to use - */ - explicit CTS_Decryption(BlockCipher* cipher) : CBC_Decryption(cipher, nullptr) {} + /** + * @param cipher block cipher to use + */ + explicit CTS_Decryption(BlockCipher* cipher) : CBC_Decryption(cipher, nullptr) {} - void finish(secure_vector& final_block, size_t offset = 0) override; + void finish(secure_vector& final_block, size_t offset = 0) override; - size_t minimum_final_size() const override; + size_t minimum_final_size() const override; - bool valid_nonce_length(size_t n) const override; - }; + bool valid_nonce_length(size_t n) const override; +}; -} +} // namespace Botan namespace Botan { /** -* This class represents Message Authentication Code (MAC) objects. -*/ -class BOTAN_PUBLIC_API(2,0) MessageAuthenticationCode : public Buffered_Computation, - public SymmetricAlgorithm - { + * This class represents Message Authentication Code (MAC) objects. + */ +class BOTAN_PUBLIC_API(2, 0) MessageAuthenticationCode : public Buffered_Computation, + public SymmetricAlgorithm { public: - /** - * Create an instance based on a name - * If provider is empty then best available is chosen. - * @param algo_spec algorithm name - * @param provider provider implementation to use - * @return a null pointer if the algo/provider combination cannot be found - */ - static std::unique_ptr - create(const std::string& algo_spec, - const std::string& provider = ""); + /** + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to use + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr create(const std::string& algo_spec, + const std::string& provider = ""); - /* - * Create an instance based on a name - * If provider is empty then best available is chosen. - * @param algo_spec algorithm name - * @param provider provider implementation to use - * Throws a Lookup_Error if algo/provider combination cannot be found - */ - static std::unique_ptr - create_or_throw(const std::string& algo_spec, - const std::string& provider = ""); + /* + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to use + * Throws a Lookup_Error if algo/provider combination cannot be found + */ + static std::unique_ptr create_or_throw( + const std::string& algo_spec, const std::string& provider = ""); - /** - * @return list of available providers for this algorithm, empty if not available - */ - static std::vector providers(const std::string& algo_spec); + /** + * @return list of available providers for this algorithm, empty if not available + */ + static std::vector providers(const std::string& algo_spec); - virtual ~MessageAuthenticationCode() = default; + virtual ~MessageAuthenticationCode() = default; - /** - * Prepare for processing a message under the specified nonce - * - * Most MACs neither require nor support a nonce; for these algorithms - * calling `start_msg` is optional and calling it with anything other than - * an empty string is an error. One MAC which *requires* a per-message - * nonce be specified is GMAC. - * - * @param nonce the message nonce bytes - * @param nonce_len the size of len in bytes - * Default implementation simply rejects all non-empty nonces - * since most hash/MAC algorithms do not support randomization - */ - virtual void start_msg(const uint8_t nonce[], size_t nonce_len); + /** + * Prepare for processing a message under the specified nonce + * + * Most MACs neither require nor support a nonce; for these algorithms + * calling `start_msg` is optional and calling it with anything other than + * an empty string is an error. One MAC which *requires* a per-message + * nonce be specified is GMAC. + * + * @param nonce the message nonce bytes + * @param nonce_len the size of len in bytes + * Default implementation simply rejects all non-empty nonces + * since most hash/MAC algorithms do not support randomization + */ + virtual void start_msg(const uint8_t nonce[], size_t nonce_len); - /** - * Begin processing a message with a nonce - * - * @param nonce the per message nonce - */ - template - void start(const std::vector& nonce) - { - start_msg(nonce.data(), nonce.size()); - } + /** + * Begin processing a message with a nonce + * + * @param nonce the per message nonce + */ + template + void start(const std::vector& nonce) { + start_msg(nonce.data(), nonce.size()); + } - /** - * Begin processing a message. - * @param nonce the per message nonce - * @param nonce_len length of nonce - */ - void start(const uint8_t nonce[], size_t nonce_len) - { - start_msg(nonce, nonce_len); - } + /** + * Begin processing a message. + * @param nonce the per message nonce + * @param nonce_len length of nonce + */ + void start(const uint8_t nonce[], size_t nonce_len) { start_msg(nonce, nonce_len); } - /** - * Begin processing a message. - */ - void start() - { - return start_msg(nullptr, 0); - } + /** + * Begin processing a message. + */ + void start() { return start_msg(nullptr, 0); } - /** - * Verify a MAC. - * @param in the MAC to verify as a byte array - * @param length the length of param in - * @return true if the MAC is valid, false otherwise - */ - virtual bool verify_mac(const uint8_t in[], size_t length); + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @param length the length of param in + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const uint8_t in[], size_t length); - /** - * Verify a MAC. - * @param in the MAC to verify as a byte array - * @return true if the MAC is valid, false otherwise - */ - virtual bool verify_mac(const std::vector& in) - { - return verify_mac(in.data(), in.size()); - } + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const std::vector& in) { + return verify_mac(in.data(), in.size()); + } - /** - * Verify a MAC. - * @param in the MAC to verify as a byte array - * @return true if the MAC is valid, false otherwise - */ - virtual bool verify_mac(const secure_vector& in) - { - return verify_mac(in.data(), in.size()); - } + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const secure_vector& in) { + return verify_mac(in.data(), in.size()); + } - /** - * Get a new object representing the same algorithm as *this - */ - virtual MessageAuthenticationCode* clone() const = 0; + /** + * Get a new object representing the same algorithm as *this + */ + virtual MessageAuthenticationCode* clone() const = 0; - /** - * @return provider information about this implementation. Default is "base", - * might also return "sse2", "avx2", "openssl", or some other arbitrary string. - */ - virtual std::string provider() const { return "base"; } - - }; + /** + * @return provider information about this implementation. Default is "base", + * might also return "sse2", "avx2", "openssl", or some other arbitrary string. + */ + virtual std::string provider() const { return "base"; } +}; typedef MessageAuthenticationCode MAC; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(cbc_mac.h) +// BOTAN_FUTURE_INTERNAL_HEADER(cbc_mac.h) namespace Botan { /** -* CBC-MAC -*/ -class BOTAN_PUBLIC_API(2,0) CBC_MAC final : public MessageAuthenticationCode - { + * CBC-MAC + */ +class BOTAN_PUBLIC_API(2, 0) CBC_MAC final : public MessageAuthenticationCode { public: - std::string name() const override; - MessageAuthenticationCode* clone() const override; - size_t output_length() const override { return m_cipher->block_size(); } - void clear() override; + std::string name() const override; + MessageAuthenticationCode* clone() const override; + size_t output_length() const override { return m_cipher->block_size(); } + void clear() override; - Key_Length_Specification key_spec() const override - { - return m_cipher->key_spec(); - } + Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } + + /** + * @param cipher the block cipher to use + */ + explicit CBC_MAC(BlockCipher* cipher); - /** - * @param cipher the block cipher to use - */ - explicit CBC_MAC(BlockCipher* cipher); private: - void add_data(const uint8_t[], size_t) override; - void final_result(uint8_t[]) override; - void key_schedule(const uint8_t[], size_t) override; + void add_data(const uint8_t[], size_t) override; + void final_result(uint8_t[]) override; + void key_schedule(const uint8_t[], size_t) override; - std::unique_ptr m_cipher; - secure_vector m_state; - size_t m_position = 0; - }; + std::unique_ptr m_cipher; + secure_vector m_state; + size_t m_position = 0; +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(charset.h) +// BOTAN_FUTURE_INTERNAL_HEADER(charset.h) namespace Botan { /** -* Convert a sequence of UCS-2 (big endian) characters to a UTF-8 string -* This is used for ASN.1 BMPString type -* @param ucs2 the sequence of UCS-2 characters -* @param len length of ucs2 in bytes, must be a multiple of 2 -*/ + * Convert a sequence of UCS-2 (big endian) characters to a UTF-8 string + * This is used for ASN.1 BMPString type + * @param ucs2 the sequence of UCS-2 characters + * @param len length of ucs2 in bytes, must be a multiple of 2 + */ std::string BOTAN_UNSTABLE_API ucs2_to_utf8(const uint8_t ucs2[], size_t len); /** -* Convert a sequence of UCS-4 (big endian) characters to a UTF-8 string -* This is used for ASN.1 UniversalString type -* @param ucs4 the sequence of UCS-4 characters -* @param len length of ucs4 in bytes, must be a multiple of 4 -*/ + * Convert a sequence of UCS-4 (big endian) characters to a UTF-8 string + * This is used for ASN.1 UniversalString type + * @param ucs4 the sequence of UCS-4 characters + * @param len length of ucs4 in bytes, must be a multiple of 4 + */ std::string BOTAN_UNSTABLE_API ucs4_to_utf8(const uint8_t ucs4[], size_t len); /** -* Convert a UTF-8 string to Latin-1 -* If a character outside the Latin-1 range is encountered, an exception is thrown. -*/ + * Convert a UTF-8 string to Latin-1 + * If a character outside the Latin-1 range is encountered, an exception is thrown. + */ std::string BOTAN_UNSTABLE_API utf8_to_latin1(const std::string& utf8); /** -* The different charsets (nominally) supported by Botan. -*/ -enum Character_Set { - LOCAL_CHARSET, - UCS2_CHARSET, - UTF8_CHARSET, - LATIN1_CHARSET -}; + * The different charsets (nominally) supported by Botan. + */ +enum Character_Set { LOCAL_CHARSET, UCS2_CHARSET, UTF8_CHARSET, LATIN1_CHARSET }; namespace Charset { /* -* Character set conversion - avoid this. -* For specific conversions, use the functions above like -* ucs2_to_utf8 and utf8_to_latin1 -* -* If you need something more complex than that, use a real library -* such as iconv, Boost.Locale, or ICU -*/ -std::string BOTAN_PUBLIC_API(2,0) - BOTAN_DEPRECATED("Avoid. See comment in header.") - transcode(const std::string& str, - Character_Set to, - Character_Set from); + * Character set conversion - avoid this. + * For specific conversions, use the functions above like + * ucs2_to_utf8 and utf8_to_latin1 + * + * If you need something more complex than that, use a real library + * such as iconv, Boost.Locale, or ICU + */ +std::string BOTAN_PUBLIC_API(2, 0) BOTAN_DEPRECATED("Avoid. See comment in header.") + transcode(const std::string& str, Character_Set to, Character_Set from); /* -* Simple character classifier functions -*/ -bool BOTAN_PUBLIC_API(2,0) is_digit(char c); -bool BOTAN_PUBLIC_API(2,0) is_space(char c); -bool BOTAN_PUBLIC_API(2,0) caseless_cmp(char x, char y); + * Simple character classifier functions + */ +bool BOTAN_PUBLIC_API(2, 0) is_digit(char c); +bool BOTAN_PUBLIC_API(2, 0) is_space(char c); +bool BOTAN_PUBLIC_API(2, 0) caseless_cmp(char x, char y); -uint8_t BOTAN_PUBLIC_API(2,0) char2digit(char c); -char BOTAN_PUBLIC_API(2,0) digit2char(uint8_t b); +uint8_t BOTAN_PUBLIC_API(2, 0) char2digit(char c); +char BOTAN_PUBLIC_API(2, 0) digit2char(uint8_t b); -} +} // namespace Charset -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(cmac.h) +// BOTAN_FUTURE_INTERNAL_HEADER(cmac.h) namespace Botan { /** -* CMAC, also known as OMAC1 -*/ -class BOTAN_PUBLIC_API(2,0) CMAC final : public MessageAuthenticationCode - { + * CMAC, also known as OMAC1 + */ +class BOTAN_PUBLIC_API(2, 0) CMAC final : public MessageAuthenticationCode { public: - std::string name() const override; - size_t output_length() const override { return m_block_size; } - MessageAuthenticationCode* clone() const override; + std::string name() const override; + size_t output_length() const override { return m_block_size; } + MessageAuthenticationCode* clone() const override; - void clear() override; + void clear() override; - Key_Length_Specification key_spec() const override - { - return m_cipher->key_spec(); - } + Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } - /** - * CMAC's polynomial doubling operation - * - * This function was only exposed for use elsewhere in the library, but it is not - * longer used. This function will be removed in a future release. - * - * @param in the input - */ - static secure_vector - BOTAN_DEPRECATED("This was only for internal use and is no longer used") - poly_double(const secure_vector& in); + /** + * CMAC's polynomial doubling operation + * + * This function was only exposed for use elsewhere in the library, but it is not + * longer used. This function will be removed in a future release. + * + * @param in the input + */ + static secure_vector BOTAN_DEPRECATED( + "This was only for internal use and is no longer used") + poly_double(const secure_vector& in); - /** - * @param cipher the block cipher to use - */ - explicit CMAC(BlockCipher* cipher); + /** + * @param cipher the block cipher to use + */ + explicit CMAC(BlockCipher* cipher); + + CMAC(const CMAC&) = delete; + CMAC& operator=(const CMAC&) = delete; - CMAC(const CMAC&) = delete; - CMAC& operator=(const CMAC&) = delete; private: - void add_data(const uint8_t[], size_t) override; - void final_result(uint8_t[]) override; - void key_schedule(const uint8_t[], size_t) override; + void add_data(const uint8_t[], size_t) override; + void final_result(uint8_t[]) override; + void key_schedule(const uint8_t[], size_t) override; - std::unique_ptr m_cipher; - secure_vector m_buffer, m_state, m_B, m_P; - const size_t m_block_size; - size_t m_position; - }; + std::unique_ptr m_cipher; + secure_vector m_buffer, m_state, m_B, m_P; + const size_t m_block_size; + size_t m_position; +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(cpuid.h) +// BOTAN_FUTURE_INTERNAL_HEADER(cpuid.h) namespace Botan { /** -* A class handling runtime CPU feature detection. It is limited to -* just the features necessary to implement CPU specific code in Botan, -* rather than being a general purpose utility. -* -* This class supports: -* -* - x86 features using CPUID. x86 is also the only processor with -* accurate cache line detection currently. -* -* - PowerPC AltiVec detection on Linux, NetBSD, OpenBSD, and macOS -* -* - ARM NEON and crypto extensions detection. On Linux and Android -* systems which support getauxval, that is used to access CPU -* feature information. Otherwise a relatively portable but -* thread-unsafe mechanism involving executing probe functions which -* catching SIGILL signal is used. -*/ -class BOTAN_PUBLIC_API(2,1) CPUID final - { + * A class handling runtime CPU feature detection. It is limited to + * just the features necessary to implement CPU specific code in Botan, + * rather than being a general purpose utility. + * + * This class supports: + * + * - x86 features using CPUID. x86 is also the only processor with + * accurate cache line detection currently. + * + * - PowerPC AltiVec detection on Linux, NetBSD, OpenBSD, and macOS + * + * - ARM NEON and crypto extensions detection. On Linux and Android + * systems which support getauxval, that is used to access CPU + * feature information. Otherwise a relatively portable but + * thread-unsafe mechanism involving executing probe functions which + * catching SIGILL signal is used. + */ +class BOTAN_PUBLIC_API(2, 1) CPUID final { public: - /** - * Probe the CPU and see what extensions are supported - */ - static void initialize(); + /** + * Probe the CPU and see what extensions are supported + */ + static void initialize(); - static bool has_simd_32(); + static bool has_simd_32(); - /** - * Deprecated equivalent to - * o << "CPUID flags: " << CPUID::to_string() << "\n"; - */ - BOTAN_DEPRECATED("Use CPUID::to_string") - static void print(std::ostream& o); + /** + * Deprecated equivalent to + * o << "CPUID flags: " << CPUID::to_string() << "\n"; + */ + BOTAN_DEPRECATED("Use CPUID::to_string") + static void print(std::ostream& o); - /** - * Return a possibly empty string containing list of known CPU - * extensions. Each name will be seperated by a space, and the ordering - * will be arbitrary. This list only contains values that are useful to - * Botan (for example FMA instructions are not checked). - * - * Example outputs "sse2 ssse3 rdtsc", "neon arm_aes", "altivec" - */ - static std::string to_string(); + /** + * Return a possibly empty string containing list of known CPU + * extensions. Each name will be seperated by a space, and the ordering + * will be arbitrary. This list only contains values that are useful to + * Botan (for example FMA instructions are not checked). + * + * Example outputs "sse2 ssse3 rdtsc", "neon arm_aes", "altivec" + */ + static std::string to_string(); - /** - * Return a best guess of the cache line size - */ - static size_t cache_line_size() - { - return state().cache_line_size(); - } + /** + * Return a best guess of the cache line size + */ + static size_t cache_line_size() { return state().cache_line_size(); } - static bool is_little_endian() - { + static bool is_little_endian() { #if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - return true; + return true; #elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - return false; + return false; #else - return state().endian_status() == Endian_Status::Little; + return state().endian_status() == Endian_Status::Little; #endif - } + } - static bool is_big_endian() - { + static bool is_big_endian() { #if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - return true; + return true; #elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - return false; + return false; #else - return state().endian_status() == Endian_Status::Big; + return state().endian_status() == Endian_Status::Big; #endif - } + } - enum CPUID_bits : uint64_t { + enum CPUID_bits : uint64_t { #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - // These values have no relation to cpuid bitfields + // These values have no relation to cpuid bitfields - // SIMD instruction sets - CPUID_SSE2_BIT = (1ULL << 0), - CPUID_SSSE3_BIT = (1ULL << 1), - CPUID_SSE41_BIT = (1ULL << 2), - CPUID_SSE42_BIT = (1ULL << 3), - CPUID_AVX2_BIT = (1ULL << 4), - CPUID_AVX512F_BIT = (1ULL << 5), + // SIMD instruction sets + CPUID_SSE2_BIT = (1ULL << 0), + CPUID_SSSE3_BIT = (1ULL << 1), + CPUID_SSE41_BIT = (1ULL << 2), + CPUID_SSE42_BIT = (1ULL << 3), + CPUID_AVX2_BIT = (1ULL << 4), + CPUID_AVX512F_BIT = (1ULL << 5), - // Misc useful instructions - CPUID_RDTSC_BIT = (1ULL << 10), - CPUID_BMI2_BIT = (1ULL << 11), - CPUID_ADX_BIT = (1ULL << 12), - CPUID_BMI1_BIT = (1ULL << 13), + // Misc useful instructions + CPUID_RDTSC_BIT = (1ULL << 10), + CPUID_BMI2_BIT = (1ULL << 11), + CPUID_ADX_BIT = (1ULL << 12), + CPUID_BMI1_BIT = (1ULL << 13), - // Crypto-specific ISAs - CPUID_AESNI_BIT = (1ULL << 16), - CPUID_CLMUL_BIT = (1ULL << 17), - CPUID_RDRAND_BIT = (1ULL << 18), - CPUID_RDSEED_BIT = (1ULL << 19), - CPUID_SHA_BIT = (1ULL << 20), + // Crypto-specific ISAs + CPUID_AESNI_BIT = (1ULL << 16), + CPUID_CLMUL_BIT = (1ULL << 17), + CPUID_RDRAND_BIT = (1ULL << 18), + CPUID_RDSEED_BIT = (1ULL << 19), + CPUID_SHA_BIT = (1ULL << 20), #endif #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - CPUID_ALTIVEC_BIT = (1ULL << 0), - CPUID_PPC_CRYPTO_BIT = (1ULL << 1), - CPUID_DARN_BIT = (1ULL << 2), + CPUID_ALTIVEC_BIT = (1ULL << 0), + CPUID_PPC_CRYPTO_BIT = (1ULL << 1), + CPUID_DARN_BIT = (1ULL << 2), #endif #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - CPUID_ARM_NEON_BIT = (1ULL << 0), - CPUID_ARM_SVE_BIT = (1ULL << 1), - CPUID_ARM_AES_BIT = (1ULL << 16), - CPUID_ARM_PMULL_BIT = (1ULL << 17), - CPUID_ARM_SHA1_BIT = (1ULL << 18), - CPUID_ARM_SHA2_BIT = (1ULL << 19), - CPUID_ARM_SHA3_BIT = (1ULL << 20), - CPUID_ARM_SHA2_512_BIT = (1ULL << 21), - CPUID_ARM_SM3_BIT = (1ULL << 22), - CPUID_ARM_SM4_BIT = (1ULL << 23), + CPUID_ARM_NEON_BIT = (1ULL << 0), + CPUID_ARM_SVE_BIT = (1ULL << 1), + CPUID_ARM_AES_BIT = (1ULL << 16), + CPUID_ARM_PMULL_BIT = (1ULL << 17), + CPUID_ARM_SHA1_BIT = (1ULL << 18), + CPUID_ARM_SHA2_BIT = (1ULL << 19), + CPUID_ARM_SHA3_BIT = (1ULL << 20), + CPUID_ARM_SHA2_512_BIT = (1ULL << 21), + CPUID_ARM_SM3_BIT = (1ULL << 22), + CPUID_ARM_SM4_BIT = (1ULL << 23), #endif - CPUID_INITIALIZED_BIT = (1ULL << 63) - }; + CPUID_INITIALIZED_BIT = (1ULL << 63) + }; #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - /** - * Check if the processor supports AltiVec/VMX - */ - static bool has_altivec() - { return has_cpuid_bit(CPUID_ALTIVEC_BIT); } + /** + * Check if the processor supports AltiVec/VMX + */ + static bool has_altivec() { return has_cpuid_bit(CPUID_ALTIVEC_BIT); } - /** - * Check if the processor supports POWER8 crypto extensions - */ - static bool has_ppc_crypto() - { return has_cpuid_bit(CPUID_PPC_CRYPTO_BIT); } + /** + * Check if the processor supports POWER8 crypto extensions + */ + static bool has_ppc_crypto() { return has_cpuid_bit(CPUID_PPC_CRYPTO_BIT); } - /** - * Check if the processor supports POWER9 DARN RNG - */ - static bool has_darn_rng() - { return has_cpuid_bit(CPUID_DARN_BIT); } + /** + * Check if the processor supports POWER9 DARN RNG + */ + static bool has_darn_rng() { return has_cpuid_bit(CPUID_DARN_BIT); } #endif #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - /** - * Check if the processor supports NEON SIMD - */ - static bool has_neon() - { return has_cpuid_bit(CPUID_ARM_NEON_BIT); } + /** + * Check if the processor supports NEON SIMD + */ + static bool has_neon() { return has_cpuid_bit(CPUID_ARM_NEON_BIT); } - /** - * Check if the processor supports ARMv8 SVE - */ - static bool has_arm_sve() - { return has_cpuid_bit(CPUID_ARM_SVE_BIT); } + /** + * Check if the processor supports ARMv8 SVE + */ + static bool has_arm_sve() { return has_cpuid_bit(CPUID_ARM_SVE_BIT); } - /** - * Check if the processor supports ARMv8 SHA1 - */ - static bool has_arm_sha1() - { return has_cpuid_bit(CPUID_ARM_SHA1_BIT); } + /** + * Check if the processor supports ARMv8 SHA1 + */ + static bool has_arm_sha1() { return has_cpuid_bit(CPUID_ARM_SHA1_BIT); } - /** - * Check if the processor supports ARMv8 SHA2 - */ - static bool has_arm_sha2() - { return has_cpuid_bit(CPUID_ARM_SHA2_BIT); } + /** + * Check if the processor supports ARMv8 SHA2 + */ + static bool has_arm_sha2() { return has_cpuid_bit(CPUID_ARM_SHA2_BIT); } - /** - * Check if the processor supports ARMv8 AES - */ - static bool has_arm_aes() - { return has_cpuid_bit(CPUID_ARM_AES_BIT); } + /** + * Check if the processor supports ARMv8 AES + */ + static bool has_arm_aes() { return has_cpuid_bit(CPUID_ARM_AES_BIT); } - /** - * Check if the processor supports ARMv8 PMULL - */ - static bool has_arm_pmull() - { return has_cpuid_bit(CPUID_ARM_PMULL_BIT); } + /** + * Check if the processor supports ARMv8 PMULL + */ + static bool has_arm_pmull() { return has_cpuid_bit(CPUID_ARM_PMULL_BIT); } - /** - * Check if the processor supports ARMv8 SHA-512 - */ - static bool has_arm_sha2_512() - { return has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); } + /** + * Check if the processor supports ARMv8 SHA-512 + */ + static bool has_arm_sha2_512() { return has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); } - /** - * Check if the processor supports ARMv8 SHA-3 - */ - static bool has_arm_sha3() - { return has_cpuid_bit(CPUID_ARM_SHA3_BIT); } + /** + * Check if the processor supports ARMv8 SHA-3 + */ + static bool has_arm_sha3() { return has_cpuid_bit(CPUID_ARM_SHA3_BIT); } - /** - * Check if the processor supports ARMv8 SM3 - */ - static bool has_arm_sm3() - { return has_cpuid_bit(CPUID_ARM_SM3_BIT); } + /** + * Check if the processor supports ARMv8 SM3 + */ + static bool has_arm_sm3() { return has_cpuid_bit(CPUID_ARM_SM3_BIT); } - /** - * Check if the processor supports ARMv8 SM4 - */ - static bool has_arm_sm4() - { return has_cpuid_bit(CPUID_ARM_SM4_BIT); } + /** + * Check if the processor supports ARMv8 SM4 + */ + static bool has_arm_sm4() { return has_cpuid_bit(CPUID_ARM_SM4_BIT); } #endif #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - /** - * Check if the processor supports RDTSC - */ - static bool has_rdtsc() - { return has_cpuid_bit(CPUID_RDTSC_BIT); } + /** + * Check if the processor supports RDTSC + */ + static bool has_rdtsc() { return has_cpuid_bit(CPUID_RDTSC_BIT); } - /** - * Check if the processor supports SSE2 - */ - static bool has_sse2() - { return has_cpuid_bit(CPUID_SSE2_BIT); } + /** + * Check if the processor supports SSE2 + */ + static bool has_sse2() { return has_cpuid_bit(CPUID_SSE2_BIT); } - /** - * Check if the processor supports SSSE3 - */ - static bool has_ssse3() - { return has_cpuid_bit(CPUID_SSSE3_BIT); } + /** + * Check if the processor supports SSSE3 + */ + static bool has_ssse3() { return has_cpuid_bit(CPUID_SSSE3_BIT); } - /** - * Check if the processor supports SSE4.1 - */ - static bool has_sse41() - { return has_cpuid_bit(CPUID_SSE41_BIT); } + /** + * Check if the processor supports SSE4.1 + */ + static bool has_sse41() { return has_cpuid_bit(CPUID_SSE41_BIT); } - /** - * Check if the processor supports SSE4.2 - */ - static bool has_sse42() - { return has_cpuid_bit(CPUID_SSE42_BIT); } + /** + * Check if the processor supports SSE4.2 + */ + static bool has_sse42() { return has_cpuid_bit(CPUID_SSE42_BIT); } - /** - * Check if the processor supports AVX2 - */ - static bool has_avx2() - { return has_cpuid_bit(CPUID_AVX2_BIT); } + /** + * Check if the processor supports AVX2 + */ + static bool has_avx2() { return has_cpuid_bit(CPUID_AVX2_BIT); } - /** - * Check if the processor supports AVX-512F - */ - static bool has_avx512f() - { return has_cpuid_bit(CPUID_AVX512F_BIT); } + /** + * Check if the processor supports AVX-512F + */ + static bool has_avx512f() { return has_cpuid_bit(CPUID_AVX512F_BIT); } - /** - * Check if the processor supports BMI1 - */ - static bool has_bmi1() - { return has_cpuid_bit(CPUID_BMI1_BIT); } + /** + * Check if the processor supports BMI1 + */ + static bool has_bmi1() { return has_cpuid_bit(CPUID_BMI1_BIT); } - /** - * Check if the processor supports BMI2 - */ - static bool has_bmi2() - { return has_cpuid_bit(CPUID_BMI2_BIT); } + /** + * Check if the processor supports BMI2 + */ + static bool has_bmi2() { return has_cpuid_bit(CPUID_BMI2_BIT); } - /** - * Check if the processor supports AES-NI - */ - static bool has_aes_ni() - { return has_cpuid_bit(CPUID_AESNI_BIT); } + /** + * Check if the processor supports AES-NI + */ + static bool has_aes_ni() { return has_cpuid_bit(CPUID_AESNI_BIT); } - /** - * Check if the processor supports CLMUL - */ - static bool has_clmul() - { return has_cpuid_bit(CPUID_CLMUL_BIT); } + /** + * Check if the processor supports CLMUL + */ + static bool has_clmul() { return has_cpuid_bit(CPUID_CLMUL_BIT); } - /** - * Check if the processor supports Intel SHA extension - */ - static bool has_intel_sha() - { return has_cpuid_bit(CPUID_SHA_BIT); } + /** + * Check if the processor supports Intel SHA extension + */ + static bool has_intel_sha() { return has_cpuid_bit(CPUID_SHA_BIT); } - /** - * Check if the processor supports ADX extension - */ - static bool has_adx() - { return has_cpuid_bit(CPUID_ADX_BIT); } + /** + * Check if the processor supports ADX extension + */ + static bool has_adx() { return has_cpuid_bit(CPUID_ADX_BIT); } - /** - * Check if the processor supports RDRAND - */ - static bool has_rdrand() - { return has_cpuid_bit(CPUID_RDRAND_BIT); } + /** + * Check if the processor supports RDRAND + */ + static bool has_rdrand() { return has_cpuid_bit(CPUID_RDRAND_BIT); } - /** - * Check if the processor supports RDSEED - */ - static bool has_rdseed() - { return has_cpuid_bit(CPUID_RDSEED_BIT); } + /** + * Check if the processor supports RDSEED + */ + static bool has_rdseed() { return has_cpuid_bit(CPUID_RDSEED_BIT); } #endif - /** - * Check if the processor supports byte-level vector permutes - * (SSSE3, NEON, Altivec) - */ - static bool has_vperm() - { + /** + * Check if the processor supports byte-level vector permutes + * (SSSE3, NEON, Altivec) + */ + static bool has_vperm() { #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - return has_ssse3(); + return has_ssse3(); #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - return has_neon(); + return has_neon(); #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - return has_altivec(); + return has_altivec(); #else - return false; + return false; #endif - } + } - /** - * Check if the processor supports carryless multiply - * (CLMUL, PMULL) - */ - static bool has_carryless_multiply() - { + /** + * Check if the processor supports carryless multiply + * (CLMUL, PMULL) + */ + static bool has_carryless_multiply() { #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - return has_clmul(); + return has_clmul(); #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - return has_arm_pmull(); + return has_arm_pmull(); #else - return false; + return false; #endif - } + } - /* - * Clear a CPUID bit - * Call CPUID::initialize to reset - * - * This is only exposed for testing, don't use unless you know - * what you are doing. - */ - static void clear_cpuid_bit(CPUID_bits bit) - { - state().clear_cpuid_bit(static_cast(bit)); - } + /* + * Clear a CPUID bit + * Call CPUID::initialize to reset + * + * This is only exposed for testing, don't use unless you know + * what you are doing. + */ + static void clear_cpuid_bit(CPUID_bits bit) { + state().clear_cpuid_bit(static_cast(bit)); + } - /* - * Don't call this function, use CPUID::has_xxx above - * It is only exposed for the tests. - */ - static bool has_cpuid_bit(CPUID_bits elem) - { - const uint64_t elem64 = static_cast(elem); - return state().has_bit(elem64); - } + /* + * Don't call this function, use CPUID::has_xxx above + * It is only exposed for the tests. + */ + static bool has_cpuid_bit(CPUID_bits elem) { + const uint64_t elem64 = static_cast(elem); + return state().has_bit(elem64); + } + + static std::vector bit_from_string(const std::string& tok); - static std::vector bit_from_string(const std::string& tok); private: - enum class Endian_Status : uint32_t { - Unknown = 0x00000000, - Big = 0x01234567, - Little = 0x67452301, - }; + enum class Endian_Status : uint32_t { + Unknown = 0x00000000, + Big = 0x01234567, + Little = 0x67452301, + }; - struct CPUID_Data - { - public: - CPUID_Data(); + struct CPUID_Data { + public: + CPUID_Data(); - CPUID_Data(const CPUID_Data& other) = default; - CPUID_Data& operator=(const CPUID_Data& other) = default; + CPUID_Data(const CPUID_Data& other) = default; + CPUID_Data& operator=(const CPUID_Data& other) = default; - void clear_cpuid_bit(uint64_t bit) - { - m_processor_features &= ~bit; - } + void clear_cpuid_bit(uint64_t bit) { m_processor_features &= ~bit; } - bool has_bit(uint64_t bit) const - { - return (m_processor_features & bit) == bit; - } + bool has_bit(uint64_t bit) const { return (m_processor_features & bit) == bit; } - uint64_t processor_features() const { return m_processor_features; } - Endian_Status endian_status() const { return m_endian_status; } - size_t cache_line_size() const { return m_cache_line_size; } + uint64_t processor_features() const { return m_processor_features; } + Endian_Status endian_status() const { return m_endian_status; } + size_t cache_line_size() const { return m_cache_line_size; } - private: - static Endian_Status runtime_check_endian(); + private: + static Endian_Status runtime_check_endian(); -#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \ - defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \ +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \ defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - static uint64_t detect_cpu_features(size_t* cache_line_size); + static uint64_t detect_cpu_features(size_t* cache_line_size); #endif - uint64_t m_processor_features; - size_t m_cache_line_size; - Endian_Status m_endian_status; - }; + uint64_t m_processor_features; + size_t m_cache_line_size; + Endian_Status m_endian_status; + }; - static CPUID_Data& state() - { - static CPUID::CPUID_Data g_cpuid; - return g_cpuid; - } - }; + static CPUID_Data& state() { + static CPUID::CPUID_Data g_cpuid; + return g_cpuid; + } +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(curve_nistp.h) +// BOTAN_FUTURE_INTERNAL_HEADER(curve_nistp.h) namespace Botan { /** -* NIST Prime reduction functions. -* -* Reduces the value in place -* -* ws is a workspace function which is used as a temporary, -* and will be resized as needed. -*/ -BOTAN_PUBLIC_API(2,0) const BigInt& prime_p521(); -BOTAN_PUBLIC_API(2,0) void redc_p521(BigInt& x, secure_vector& ws); + * NIST Prime reduction functions. + * + * Reduces the value in place + * + * ws is a workspace function which is used as a temporary, + * and will be resized as needed. + */ +BOTAN_PUBLIC_API(2, 0) const BigInt& prime_p521(); +BOTAN_PUBLIC_API(2, 0) void redc_p521(BigInt& x, secure_vector& ws); /* Previously this macro indicated if the P-{192,224,256,384} reducers @@ -6657,309 +6083,293 @@ The define will be removed in a future major release. */ #define BOTAN_HAS_NIST_PRIME_REDUCERS_W32 -BOTAN_PUBLIC_API(2,0) const BigInt& prime_p384(); -BOTAN_PUBLIC_API(2,0) void redc_p384(BigInt& x, secure_vector& ws); +BOTAN_PUBLIC_API(2, 0) const BigInt& prime_p384(); +BOTAN_PUBLIC_API(2, 0) void redc_p384(BigInt& x, secure_vector& ws); -BOTAN_PUBLIC_API(2,0) const BigInt& prime_p256(); -BOTAN_PUBLIC_API(2,0) void redc_p256(BigInt& x, secure_vector& ws); +BOTAN_PUBLIC_API(2, 0) const BigInt& prime_p256(); +BOTAN_PUBLIC_API(2, 0) void redc_p256(BigInt& x, secure_vector& ws); -BOTAN_PUBLIC_API(2,0) const BigInt& prime_p224(); -BOTAN_PUBLIC_API(2,0) void redc_p224(BigInt& x, secure_vector& ws); +BOTAN_PUBLIC_API(2, 0) const BigInt& prime_p224(); +BOTAN_PUBLIC_API(2, 0) void redc_p224(BigInt& x, secure_vector& ws); -BOTAN_PUBLIC_API(2,0) const BigInt& prime_p192(); -BOTAN_PUBLIC_API(2,0) void redc_p192(BigInt& x, secure_vector& ws); +BOTAN_PUBLIC_API(2, 0) const BigInt& prime_p192(); +BOTAN_PUBLIC_API(2, 0) void redc_p192(BigInt& x, secure_vector& ws); -} +} // namespace Botan namespace Botan { /** -* This class represents general abstract filter objects. -*/ -class BOTAN_PUBLIC_API(2,0) Filter - { + * This class represents general abstract filter objects. + */ +class BOTAN_PUBLIC_API(2, 0) Filter { public: - /** - * @return descriptive name for this filter - */ - virtual std::string name() const = 0; + /** + * @return descriptive name for this filter + */ + virtual std::string name() const = 0; - /** - * Write a portion of a message to this filter. - * @param input the input as a byte array - * @param length the length of the byte array input - */ - virtual void write(const uint8_t input[], size_t length) = 0; + /** + * Write a portion of a message to this filter. + * @param input the input as a byte array + * @param length the length of the byte array input + */ + virtual void write(const uint8_t input[], size_t length) = 0; - /** - * Start a new message. Must be closed by end_msg() before another - * message can be started. - */ - virtual void start_msg() { /* default empty */ } + /** + * Start a new message. Must be closed by end_msg() before another + * message can be started. + */ + virtual void start_msg() { /* default empty */ } - /** - * Notify that the current message is finished; flush buffers and - * do end-of-message processing (if any). - */ - virtual void end_msg() { /* default empty */ } + /** + * Notify that the current message is finished; flush buffers and + * do end-of-message processing (if any). + */ + virtual void end_msg() { /* default empty */ } - /** - * Check whether this filter is an attachable filter. - * @return true if this filter is attachable, false otherwise - */ - virtual bool attachable() { return true; } + /** + * Check whether this filter is an attachable filter. + * @return true if this filter is attachable, false otherwise + */ + virtual bool attachable() { return true; } + + virtual ~Filter() = default; - virtual ~Filter() = default; protected: - /** - * @param in some input for the filter - * @param length the length of in - */ - virtual void send(const uint8_t in[], size_t length); + /** + * @param in some input for the filter + * @param length the length of in + */ + virtual void send(const uint8_t in[], size_t length); - /** - * @param in some input for the filter - */ - void send(uint8_t in) { send(&in, 1); } + /** + * @param in some input for the filter + */ + void send(uint8_t in) { send(&in, 1); } - /** - * @param in some input for the filter - */ - template - void send(const std::vector& in) - { - send(in.data(), in.size()); - } + /** + * @param in some input for the filter + */ + template + void send(const std::vector& in) { + send(in.data(), in.size()); + } - /** - * @param in some input for the filter - * @param length the number of bytes of in to send - */ - template - void send(const std::vector& in, size_t length) - { - BOTAN_ASSERT_NOMSG(length <= in.size()); - send(in.data(), length); - } + /** + * @param in some input for the filter + * @param length the number of bytes of in to send + */ + template + void send(const std::vector& in, size_t length) { + BOTAN_ASSERT_NOMSG(length <= in.size()); + send(in.data(), length); + } - Filter(); + Filter(); - Filter(const Filter&) = delete; + Filter(const Filter&) = delete; - Filter& operator=(const Filter&) = delete; + Filter& operator=(const Filter&) = delete; private: - /** - * Start a new message in *this and all following filters. Only for - * internal use, not intended for use in client applications. - */ - void new_msg(); + /** + * Start a new message in *this and all following filters. Only for + * internal use, not intended for use in client applications. + */ + void new_msg(); - /** - * End a new message in *this and all following filters. Only for - * internal use, not intended for use in client applications. - */ - void finish_msg(); + /** + * End a new message in *this and all following filters. Only for + * internal use, not intended for use in client applications. + */ + void finish_msg(); - friend class Pipe; - friend class Fanout_Filter; + friend class Pipe; + friend class Fanout_Filter; - size_t total_ports() const; - size_t current_port() const { return m_port_num; } + size_t total_ports() const; + size_t current_port() const { return m_port_num; } - /** - * Set the active port - * @param new_port the new value - */ - void set_port(size_t new_port); + /** + * Set the active port + * @param new_port the new value + */ + void set_port(size_t new_port); - size_t owns() const { return m_filter_owns; } + size_t owns() const { return m_filter_owns; } - /** - * Attach another filter to this one - * @param f filter to attach - */ - void attach(Filter* f); + /** + * Attach another filter to this one + * @param f filter to attach + */ + void attach(Filter* f); - /** - * @param filters the filters to set - * @param count number of items in filters - */ - void set_next(Filter* filters[], size_t count); - Filter* get_next() const; + /** + * @param filters the filters to set + * @param count number of items in filters + */ + void set_next(Filter* filters[], size_t count); + Filter* get_next() const; - secure_vector m_write_queue; - std::vector m_next; // not owned - size_t m_port_num, m_filter_owns; + secure_vector m_write_queue; + std::vector m_next; // not owned + size_t m_port_num, m_filter_owns; - // true if filter belongs to a pipe --> prohibit filter sharing! - bool m_owned; - }; + // true if filter belongs to a pipe --> prohibit filter sharing! + bool m_owned; +}; /** -* This is the abstract Fanout_Filter base class. -**/ -class BOTAN_PUBLIC_API(2,0) Fanout_Filter : public Filter - { + * This is the abstract Fanout_Filter base class. + **/ +class BOTAN_PUBLIC_API(2, 0) Fanout_Filter : public Filter { protected: - /** - * Increment the number of filters past us that we own - */ - void incr_owns() { ++m_filter_owns; } + /** + * Increment the number of filters past us that we own + */ + void incr_owns() { ++m_filter_owns; } - void set_port(size_t n) { Filter::set_port(n); } + void set_port(size_t n) { Filter::set_port(n); } - void set_next(Filter* f[], size_t n) { Filter::set_next(f, n); } + void set_next(Filter* f[], size_t n) { Filter::set_next(f, n); } - void attach(Filter* f) { Filter::attach(f); } + void attach(Filter* f) { Filter::attach(f); } private: - friend class Threaded_Fork; - using Filter::m_write_queue; - using Filter::total_ports; - using Filter::m_next; - }; + friend class Threaded_Fork; + using Filter::m_next; + using Filter::m_write_queue; + using Filter::total_ports; +}; /** -* The type of checking to be performed by decoders: -* NONE - no checks, IGNORE_WS - perform checks, but ignore -* whitespaces, FULL_CHECK - perform checks, also complain -* about white spaces. -*/ + * The type of checking to be performed by decoders: + * NONE - no checks, IGNORE_WS - perform checks, but ignore + * whitespaces, FULL_CHECK - perform checks, also complain + * about white spaces. + */ enum Decoder_Checking { NONE, IGNORE_WS, FULL_CHECK }; -} +} // namespace Botan namespace Botan { /** -* This class represents abstract data sink objects. -*/ -class BOTAN_PUBLIC_API(2,0) DataSink : public Filter - { + * This class represents abstract data sink objects. + */ +class BOTAN_PUBLIC_API(2, 0) DataSink : public Filter { public: - bool attachable() override { return false; } - DataSink() = default; - virtual ~DataSink() = default; + bool attachable() override { return false; } + DataSink() = default; + virtual ~DataSink() = default; - DataSink& operator=(const DataSink&) = delete; - DataSink(const DataSink&) = delete; - }; + DataSink& operator=(const DataSink&) = delete; + DataSink(const DataSink&) = delete; +}; /** -* This class represents a data sink which writes its output to a stream. -*/ -class BOTAN_PUBLIC_API(2,0) DataSink_Stream final : public DataSink - { + * This class represents a data sink which writes its output to a stream. + */ +class BOTAN_PUBLIC_API(2, 0) DataSink_Stream final : public DataSink { public: - /** - * Construct a DataSink_Stream from a stream. - * @param stream the stream to write to - * @param name identifier - */ - DataSink_Stream(std::ostream& stream, - const std::string& name = ""); + /** + * Construct a DataSink_Stream from a stream. + * @param stream the stream to write to + * @param name identifier + */ + DataSink_Stream(std::ostream& stream, const std::string& name = ""); #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) - /** - * Construct a DataSink_Stream from a filesystem path name. - * @param pathname the name of the file to open a stream to - * @param use_binary indicates whether to treat the file - * as a binary file or not - */ - DataSink_Stream(const std::string& pathname, - bool use_binary = false); + /** + * Construct a DataSink_Stream from a filesystem path name. + * @param pathname the name of the file to open a stream to + * @param use_binary indicates whether to treat the file + * as a binary file or not + */ + DataSink_Stream(const std::string& pathname, bool use_binary = false); #endif - std::string name() const override { return m_identifier; } + std::string name() const override { return m_identifier; } - void write(const uint8_t[], size_t) override; + void write(const uint8_t[], size_t) override; - void end_msg() override; + void end_msg() override; - ~DataSink_Stream(); + ~DataSink_Stream(); private: - const std::string m_identifier; + const std::string m_identifier; - // May be null, if m_sink was an external reference - std::unique_ptr m_sink_memory; - std::ostream& m_sink; - }; + // May be null, if m_sink was an external reference + std::unique_ptr m_sink_memory; + std::ostream& m_sink; +}; -} +} // namespace Botan namespace Botan { -class BOTAN_PUBLIC_API(2,0) SQL_Database - { +class BOTAN_PUBLIC_API(2, 0) SQL_Database { public: + class BOTAN_PUBLIC_API(2, 0) SQL_DB_Error final : public Exception { + public: + explicit SQL_DB_Error(const std::string& what) : Exception("SQL database", what), m_rc(0) {} - class BOTAN_PUBLIC_API(2,0) SQL_DB_Error final : public Exception - { - public: - explicit SQL_DB_Error(const std::string& what) : - Exception("SQL database", what), - m_rc(0) - {} + SQL_DB_Error(const std::string& what, int rc) : Exception("SQL database", what), m_rc(rc) {} - SQL_DB_Error(const std::string& what, int rc) : - Exception("SQL database", what), - m_rc(rc) - {} + ErrorType error_type() const noexcept override { return Botan::ErrorType::DatabaseError; } - ErrorType error_type() const noexcept override { return Botan::ErrorType::DatabaseError; } + int error_code() const noexcept override { return m_rc; } - int error_code() const noexcept override { return m_rc; } - private: - int m_rc; - }; + private: + int m_rc; + }; - class BOTAN_PUBLIC_API(2,0) Statement - { - public: - /* Bind statement parameters */ - virtual void bind(int column, const std::string& str) = 0; + class BOTAN_PUBLIC_API(2, 0) Statement { + public: + /* Bind statement parameters */ + virtual void bind(int column, const std::string& str) = 0; - virtual void bind(int column, size_t i) = 0; + virtual void bind(int column, size_t i) = 0; - virtual void bind(int column, std::chrono::system_clock::time_point time) = 0; + virtual void bind(int column, std::chrono::system_clock::time_point time) = 0; - virtual void bind(int column, const std::vector& blob) = 0; + virtual void bind(int column, const std::vector& blob) = 0; - virtual void bind(int column, const uint8_t* data, size_t len) = 0; + virtual void bind(int column, const uint8_t* data, size_t len) = 0; - /* Get output */ - virtual std::pair get_blob(int column) = 0; + /* Get output */ + virtual std::pair get_blob(int column) = 0; - virtual std::string get_str(int column) = 0; + virtual std::string get_str(int column) = 0; - virtual size_t get_size_t(int column) = 0; + virtual size_t get_size_t(int column) = 0; - /* Run to completion */ - virtual size_t spin() = 0; + /* Run to completion */ + virtual size_t spin() = 0; - /* Maybe update */ - virtual bool step() = 0; + /* Maybe update */ + virtual bool step() = 0; - virtual ~Statement() = default; - }; + virtual ~Statement() = default; + }; - /* - * Create a new statement for execution. - * Use ?1, ?2, ?3, etc for parameters to set later with bind - */ - virtual std::shared_ptr new_statement(const std::string& base_sql) const = 0; + /* + * Create a new statement for execution. + * Use ?1, ?2, ?3, etc for parameters to set later with bind + */ + virtual std::shared_ptr new_statement(const std::string& base_sql) const = 0; - virtual size_t row_count(const std::string& table_name) = 0; + virtual size_t row_count(const std::string& table_name) = 0; - virtual void create_table(const std::string& table_schema) = 0; + virtual void create_table(const std::string& table_schema) = 0; - virtual ~SQL_Database() = default; + virtual ~SQL_Database() = default; }; -} +} // namespace Botan namespace Botan { @@ -6967,367 +6377,318 @@ class BigInt; class ASN1_Object; /** -* General DER Encoding Object -*/ -class BOTAN_PUBLIC_API(2,0) DER_Encoder final - { + * General DER Encoding Object + */ +class BOTAN_PUBLIC_API(2, 0) DER_Encoder final { public: - typedef std::function append_fn; + typedef std::function append_fn; - /** - * DER encode, writing to an internal buffer - * Use get_contents or get_contents_unlocked to read the results - * after all encoding is completed. - */ - DER_Encoder() = default; + /** + * DER encode, writing to an internal buffer + * Use get_contents or get_contents_unlocked to read the results + * after all encoding is completed. + */ + DER_Encoder() = default; - /** - * DER encode, writing to @param vec - * If this constructor is used, get_contents* may not be called. - */ - DER_Encoder(secure_vector& vec); + /** + * DER encode, writing to @param vec + * If this constructor is used, get_contents* may not be called. + */ + DER_Encoder(secure_vector& vec); - /** - * DER encode, writing to @param vec - * If this constructor is used, get_contents* may not be called. - */ - DER_Encoder(std::vector& vec); + /** + * DER encode, writing to @param vec + * If this constructor is used, get_contents* may not be called. + */ + DER_Encoder(std::vector& vec); - /** - * DER encode, calling append to write output - * If this constructor is used, get_contents* may not be called. - */ - DER_Encoder(append_fn append) : m_append_output(append) {} + /** + * DER encode, calling append to write output + * If this constructor is used, get_contents* may not be called. + */ + DER_Encoder(append_fn append) : m_append_output(append) {} - secure_vector get_contents(); + secure_vector get_contents(); - std::vector get_contents_unlocked(); + std::vector get_contents_unlocked(); - DER_Encoder& start_cons(ASN1_Tag type_tag, - ASN1_Tag class_tag = UNIVERSAL); - DER_Encoder& end_cons(); + DER_Encoder& start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL); + DER_Encoder& end_cons(); - DER_Encoder& start_explicit(uint16_t type_tag); - DER_Encoder& end_explicit(); + DER_Encoder& start_explicit(uint16_t type_tag); + DER_Encoder& end_explicit(); - /** - * Insert raw bytes directly into the output stream - */ - DER_Encoder& raw_bytes(const uint8_t val[], size_t len); + /** + * Insert raw bytes directly into the output stream + */ + DER_Encoder& raw_bytes(const uint8_t val[], size_t len); - template - DER_Encoder& raw_bytes(const std::vector& val) - { - return raw_bytes(val.data(), val.size()); - } + template + DER_Encoder& raw_bytes(const std::vector& val) { + return raw_bytes(val.data(), val.size()); + } - DER_Encoder& encode_null(); - DER_Encoder& encode(bool b); - DER_Encoder& encode(size_t s); - DER_Encoder& encode(const BigInt& n); - DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Tag real_type); + DER_Encoder& encode_null(); + DER_Encoder& encode(bool b); + DER_Encoder& encode(size_t s); + DER_Encoder& encode(const BigInt& n); + DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Tag real_type); - template - DER_Encoder& encode(const std::vector& vec, ASN1_Tag real_type) - { - return encode(vec.data(), vec.size(), real_type); - } + template + DER_Encoder& encode(const std::vector& vec, ASN1_Tag real_type) { + return encode(vec.data(), vec.size(), real_type); + } - DER_Encoder& encode(bool b, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + DER_Encoder& encode(bool b, ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(size_t s, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + DER_Encoder& encode(size_t s, ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(const BigInt& n, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + DER_Encoder& encode(const BigInt& n, ASN1_Tag type_tag, ASN1_Tag class_tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(const uint8_t v[], size_t len, - ASN1_Tag real_type, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); + DER_Encoder& encode(const uint8_t v[], size_t len, ASN1_Tag real_type, ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); - template - DER_Encoder& encode(const std::vector& bytes, - ASN1_Tag real_type, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - return encode(bytes.data(), bytes.size(), - real_type, type_tag, class_tag); - } + template + DER_Encoder& encode(const std::vector& bytes, ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) { + return encode(bytes.data(), bytes.size(), real_type, type_tag, class_tag); + } - template - DER_Encoder& encode_optional(const T& value, const T& default_value) - { - if(value != default_value) - encode(value); - return (*this); - } + template + DER_Encoder& encode_optional(const T& value, const T& default_value) { + if (value != default_value) encode(value); + return (*this); + } - template - DER_Encoder& encode_list(const std::vector& values) - { - for(size_t i = 0; i != values.size(); ++i) - encode(values[i]); - return (*this); - } + template + DER_Encoder& encode_list(const std::vector& values) { + for (size_t i = 0; i != values.size(); ++i) encode(values[i]); + return (*this); + } - /* - * Request for an object to encode itself to this stream - */ - DER_Encoder& encode(const ASN1_Object& obj); + /* + * Request for an object to encode itself to this stream + */ + DER_Encoder& encode(const ASN1_Object& obj); - /* - * Conditionally write some values to the stream - */ - DER_Encoder& encode_if(bool pred, DER_Encoder& enc) - { - if(pred) - return raw_bytes(enc.get_contents()); - return (*this); - } + /* + * Conditionally write some values to the stream + */ + DER_Encoder& encode_if(bool pred, DER_Encoder& enc) { + if (pred) return raw_bytes(enc.get_contents()); + return (*this); + } - DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) - { - if(pred) - encode(obj); - return (*this); - } + DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) { + if (pred) encode(obj); + return (*this); + } - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const uint8_t rep[], size_t length); + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const uint8_t rep[], + size_t length); - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const std::vector& rep) - { - return add_object(type_tag, class_tag, rep.data(), rep.size()); - } + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::vector& rep) { + return add_object(type_tag, class_tag, rep.data(), rep.size()); + } - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const secure_vector& rep) - { - return add_object(type_tag, class_tag, rep.data(), rep.size()); - } + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const secure_vector& rep) { + return add_object(type_tag, class_tag, rep.data(), rep.size()); + } - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const std::string& str); + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const std::string& str); - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - uint8_t val); + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, uint8_t val); private: - class DER_Sequence final - { - public: - ASN1_Tag tag_of() const; + class DER_Sequence final { + public: + ASN1_Tag tag_of() const; - void push_contents(DER_Encoder& der); + void push_contents(DER_Encoder& der); - void add_bytes(const uint8_t val[], size_t len); + void add_bytes(const uint8_t val[], size_t len); - void add_bytes(const uint8_t hdr[], size_t hdr_len, - const uint8_t val[], size_t val_len); + void add_bytes(const uint8_t hdr[], size_t hdr_len, const uint8_t val[], size_t val_len); - DER_Sequence(ASN1_Tag, ASN1_Tag); + DER_Sequence(ASN1_Tag, ASN1_Tag); - DER_Sequence(DER_Sequence&& seq) - { - std::swap(m_type_tag, seq.m_type_tag); - std::swap(m_class_tag, seq.m_class_tag); - std::swap(m_contents, seq.m_contents); - std::swap(m_set_contents, seq.m_set_contents); - } + DER_Sequence(DER_Sequence&& seq) { + std::swap(m_type_tag, seq.m_type_tag); + std::swap(m_class_tag, seq.m_class_tag); + std::swap(m_contents, seq.m_contents); + std::swap(m_set_contents, seq.m_set_contents); + } - DER_Sequence& operator=(DER_Sequence&& seq) - { - std::swap(m_type_tag, seq.m_type_tag); - std::swap(m_class_tag, seq.m_class_tag); - std::swap(m_contents, seq.m_contents); - std::swap(m_set_contents, seq.m_set_contents); - return (*this); - } + DER_Sequence& operator=(DER_Sequence&& seq) { + std::swap(m_type_tag, seq.m_type_tag); + std::swap(m_class_tag, seq.m_class_tag); + std::swap(m_contents, seq.m_contents); + std::swap(m_set_contents, seq.m_set_contents); + return (*this); + } - DER_Sequence(const DER_Sequence& seq) = default; + DER_Sequence(const DER_Sequence& seq) = default; - DER_Sequence& operator=(const DER_Sequence& seq) = default; + DER_Sequence& operator=(const DER_Sequence& seq) = default; - private: - ASN1_Tag m_type_tag, m_class_tag; - secure_vector m_contents; - std::vector< secure_vector > m_set_contents; - }; + private: + ASN1_Tag m_type_tag, m_class_tag; + secure_vector m_contents; + std::vector> m_set_contents; + }; - append_fn m_append_output; - secure_vector m_default_outbuf; - std::vector m_subsequences; - }; + append_fn m_append_output; + secure_vector m_default_outbuf; + std::vector m_subsequences; +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(divide.h) +// BOTAN_FUTURE_INTERNAL_HEADER(divide.h) namespace Botan { /** -* BigInt Division -* @param x an integer -* @param y a non-zero integer -* @param q will be set to x / y -* @param r will be set to x % y -*/ -void BOTAN_PUBLIC_API(2,0) divide(const BigInt& x, - const BigInt& y, - BigInt& q, - BigInt& r); + * BigInt Division + * @param x an integer + * @param y a non-zero integer + * @param q will be set to x / y + * @param r will be set to x % y + */ +void BOTAN_PUBLIC_API(2, 0) divide(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r); /** -* BigInt division, const time variant -* -* This runs with control flow independent of the values of x/y. -* Warning: the loop bounds still leak the sizes of x and y. -* -* @param x an integer -* @param y a non-zero integer -* @param q will be set to x / y -* @param r will be set to x % y -*/ -void BOTAN_PUBLIC_API(2,9) ct_divide(const BigInt& x, - const BigInt& y, - BigInt& q, - BigInt& r); + * BigInt division, const time variant + * + * This runs with control flow independent of the values of x/y. + * Warning: the loop bounds still leak the sizes of x and y. + * + * @param x an integer + * @param y a non-zero integer + * @param q will be set to x / y + * @param r will be set to x % y + */ +void BOTAN_PUBLIC_API(2, 9) ct_divide(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r); /** -* BigInt division, const time variant -* -* This runs with control flow independent of the values of x/y. -* Warning: the loop bounds still leak the sizes of x and y. -* -* @param x an integer -* @param y a non-zero integer -* @return x/y with remainder discarded -*/ -inline BigInt ct_divide(const BigInt& x, const BigInt& y) - { - BigInt q, r; - ct_divide(x, y, q, r); - return q; - } - -/** -* BigInt division, const time variant -* -* This runs with control flow independent of the values of x/y. -* Warning: the loop bounds still leak the sizes of x and y. -* -* @param x an integer -* @param y a non-zero integer -* @param q will be set to x / y -* @param r will be set to x % y -*/ -void BOTAN_PUBLIC_API(2,9) ct_divide_u8(const BigInt& x, - uint8_t y, - BigInt& q, - uint8_t& r); - -/** -* BigInt modulo, const time variant -* -* Using this function is (slightly) cheaper than calling ct_divide and -* using only the remainder. -* -* @param x a non-negative integer -* @param modulo a positive integer -* @return result x % modulo -*/ -BigInt BOTAN_PUBLIC_API(2,9) ct_modulo(const BigInt& x, - const BigInt& modulo); - + * BigInt division, const time variant + * + * This runs with control flow independent of the values of x/y. + * Warning: the loop bounds still leak the sizes of x and y. + * + * @param x an integer + * @param y a non-zero integer + * @return x/y with remainder discarded + */ +inline BigInt ct_divide(const BigInt& x, const BigInt& y) { + BigInt q, r; + ct_divide(x, y, q, r); + return q; } -//BOTAN_FUTURE_INTERNAL_HEADER(eme.h) +/** + * BigInt division, const time variant + * + * This runs with control flow independent of the values of x/y. + * Warning: the loop bounds still leak the sizes of x and y. + * + * @param x an integer + * @param y a non-zero integer + * @param q will be set to x / y + * @param r will be set to x % y + */ +void BOTAN_PUBLIC_API(2, 9) ct_divide_u8(const BigInt& x, uint8_t y, BigInt& q, uint8_t& r); + +/** + * BigInt modulo, const time variant + * + * Using this function is (slightly) cheaper than calling ct_divide and + * using only the remainder. + * + * @param x a non-negative integer + * @param modulo a positive integer + * @return result x % modulo + */ +BigInt BOTAN_PUBLIC_API(2, 9) ct_modulo(const BigInt& x, const BigInt& modulo); + +} // namespace Botan + +// BOTAN_FUTURE_INTERNAL_HEADER(eme.h) namespace Botan { class RandomNumberGenerator; /** -* Encoding Method for Encryption -*/ -class BOTAN_PUBLIC_API(2,0) EME - { + * Encoding Method for Encryption + */ +class BOTAN_PUBLIC_API(2, 0) EME { public: - virtual ~EME() = default; + virtual ~EME() = default; - /** - * Return the maximum input size in bytes we can support - * @param keybits the size of the key in bits - * @return upper bound of input in bytes - */ - virtual size_t maximum_input_size(size_t keybits) const = 0; + /** + * Return the maximum input size in bytes we can support + * @param keybits the size of the key in bits + * @return upper bound of input in bytes + */ + virtual size_t maximum_input_size(size_t keybits) const = 0; - /** - * Encode an input - * @param in the plaintext - * @param in_length length of plaintext in bytes - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - secure_vector encode(const uint8_t in[], - size_t in_length, - size_t key_length, - RandomNumberGenerator& rng) const; + /** + * Encode an input + * @param in the plaintext + * @param in_length length of plaintext in bytes + * @param key_length length of the key in bits + * @param rng a random number generator + * @return encoded plaintext + */ + secure_vector encode(const uint8_t in[], size_t in_length, size_t key_length, + RandomNumberGenerator& rng) const; - /** - * Encode an input - * @param in the plaintext - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - secure_vector encode(const secure_vector& in, - size_t key_length, - RandomNumberGenerator& rng) const; + /** + * Encode an input + * @param in the plaintext + * @param key_length length of the key in bits + * @param rng a random number generator + * @return encoded plaintext + */ + secure_vector encode(const secure_vector& in, size_t key_length, + RandomNumberGenerator& rng) const; - /** - * Decode an input - * @param valid_mask written to specifies if output is valid - * @param in the encoded plaintext - * @param in_len length of encoded plaintext in bytes - * @return bytes of out[] written to along with - * validity mask (0xFF if valid, else 0x00) - */ - virtual secure_vector unpad(uint8_t& valid_mask, - const uint8_t in[], - size_t in_len) const = 0; + /** + * Decode an input + * @param valid_mask written to specifies if output is valid + * @param in the encoded plaintext + * @param in_len length of encoded plaintext in bytes + * @return bytes of out[] written to along with + * validity mask (0xFF if valid, else 0x00) + */ + virtual secure_vector unpad(uint8_t& valid_mask, const uint8_t in[], + size_t in_len) const = 0; - /** - * Encode an input - * @param in the plaintext - * @param in_length length of plaintext in bytes - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - virtual secure_vector pad(const uint8_t in[], - size_t in_length, - size_t key_length, - RandomNumberGenerator& rng) const = 0; - }; + /** + * Encode an input + * @param in the plaintext + * @param in_length length of plaintext in bytes + * @param key_length length of the key in bits + * @param rng a random number generator + * @return encoded plaintext + */ + virtual secure_vector pad(const uint8_t in[], size_t in_length, size_t key_length, + RandomNumberGenerator& rng) const = 0; +}; /** -* Factory method for EME (message-encoding methods for encryption) objects -* @param algo_spec the name of the EME to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_PUBLIC_API(2,0) EME* get_eme(const std::string& algo_spec); + * Factory method for EME (message-encoding methods for encryption) objects + * @param algo_spec the name of the EME to create + * @return pointer to newly allocated object of that type + */ +BOTAN_PUBLIC_API(2, 0) EME* get_eme(const std::string& algo_spec); -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(emsa.h) +// BOTAN_FUTURE_INTERNAL_HEADER(emsa.h) namespace Botan { @@ -7335,99 +6696,96 @@ class Private_Key; class RandomNumberGenerator; /** -* EMSA, from IEEE 1363s Encoding Method for Signatures, Appendix -* -* Any way of encoding/padding signatures -*/ -class BOTAN_PUBLIC_API(2,0) EMSA - { + * EMSA, from IEEE 1363s Encoding Method for Signatures, Appendix + * + * Any way of encoding/padding signatures + */ +class BOTAN_PUBLIC_API(2, 0) EMSA { public: - virtual ~EMSA() = default; + virtual ~EMSA() = default; - /** - * Add more data to the signature computation - * @param input some data - * @param length length of input in bytes - */ - virtual void update(const uint8_t input[], size_t length) = 0; + /** + * Add more data to the signature computation + * @param input some data + * @param length length of input in bytes + */ + virtual void update(const uint8_t input[], size_t length) = 0; - /** - * @return raw hash - */ - virtual secure_vector raw_data() = 0; + /** + * @return raw hash + */ + virtual secure_vector raw_data() = 0; - /** - * Return the encoding of a message - * @param msg the result of raw_data() - * @param output_bits the desired output bit size - * @param rng a random number generator - * @return encoded signature - */ - virtual secure_vector encoding_of(const secure_vector& msg, - size_t output_bits, - RandomNumberGenerator& rng) = 0; + /** + * Return the encoding of a message + * @param msg the result of raw_data() + * @param output_bits the desired output bit size + * @param rng a random number generator + * @return encoded signature + */ + virtual secure_vector encoding_of(const secure_vector& msg, + size_t output_bits, RandomNumberGenerator& rng) = 0; - /** - * Verify the encoding - * @param coded the received (coded) message representative - * @param raw the computed (local, uncoded) message representative - * @param key_bits the size of the key in bits - * @return true if coded is a valid encoding of raw, otherwise false - */ - virtual bool verify(const secure_vector& coded, - const secure_vector& raw, - size_t key_bits) = 0; + /** + * Verify the encoding + * @param coded the received (coded) message representative + * @param raw the computed (local, uncoded) message representative + * @param key_bits the size of the key in bits + * @return true if coded is a valid encoding of raw, otherwise false + */ + virtual bool verify(const secure_vector& coded, const secure_vector& raw, + size_t key_bits) = 0; - /** - * Prepare sig_algo for use in choose_sig_format for x509 certs - * - * @param key used for checking compatibility with the encoding scheme - * @param cert_hash_name is checked to equal the hash for the encoding - * @return algorithm identifier to signatures created using this key, - * padding method and hash. - */ - virtual AlgorithmIdentifier config_for_x509(const Private_Key& key, - const std::string& cert_hash_name) const; + /** + * Prepare sig_algo for use in choose_sig_format for x509 certs + * + * @param key used for checking compatibility with the encoding scheme + * @param cert_hash_name is checked to equal the hash for the encoding + * @return algorithm identifier to signatures created using this key, + * padding method and hash. + */ + virtual AlgorithmIdentifier config_for_x509(const Private_Key& key, + const std::string& cert_hash_name) const; - /** - * @return a new object representing the same encoding method as *this - */ - virtual EMSA* clone() = 0; + /** + * @return a new object representing the same encoding method as *this + */ + virtual EMSA* clone() = 0; - /** - * @return the SCAN name of the encoding/padding scheme - */ - virtual std::string name() const = 0; - }; + /** + * @return the SCAN name of the encoding/padding scheme + */ + virtual std::string name() const = 0; +}; /** -* Factory method for EMSA (message-encoding methods for signatures -* with appendix) objects -* @param algo_spec the name of the EMSA to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_PUBLIC_API(2,0) EMSA* get_emsa(const std::string& algo_spec); + * Factory method for EMSA (message-encoding methods for signatures + * with appendix) objects + * @param algo_spec the name of the EMSA to create + * @return pointer to newly allocated object of that type + */ +BOTAN_PUBLIC_API(2, 0) EMSA* get_emsa(const std::string& algo_spec); /** -* Returns the hash function used in the given EMSA scheme -* If the hash function is not specified or not understood, -* returns "SHA-512" -* @param algo_spec the name of the EMSA -* @return hash function used in the given EMSA scheme -*/ -BOTAN_PUBLIC_API(2,0) std::string hash_for_emsa(const std::string& algo_spec); + * Returns the hash function used in the given EMSA scheme + * If the hash function is not specified or not understood, + * returns "SHA-512" + * @param algo_spec the name of the EMSA + * @return hash function used in the given EMSA scheme + */ +BOTAN_PUBLIC_API(2, 0) std::string hash_for_emsa(const std::string& algo_spec); -} +} // namespace Botan #if defined(BOTAN_TARGET_OS_HAS_THREADS) - namespace Botan { -template using lock_guard_type = std::lock_guard; +template +using lock_guard_type = std::lock_guard; typedef std::mutex mutex_type; -} +} // namespace Botan #else @@ -7435,32 +6793,31 @@ typedef std::mutex mutex_type; namespace Botan { -template -class lock_guard final - { +template +class lock_guard final { public: - explicit lock_guard(Mutex& m) : m_mutex(m) - { m_mutex.lock(); } + explicit lock_guard(Mutex& m) : m_mutex(m) { m_mutex.lock(); } - ~lock_guard() { m_mutex.unlock(); } + ~lock_guard() { m_mutex.unlock(); } + + lock_guard(const lock_guard& other) = delete; + lock_guard& operator=(const lock_guard& other) = delete; - lock_guard(const lock_guard& other) = delete; - lock_guard& operator=(const lock_guard& other) = delete; private: - Mutex& m_mutex; - }; + Mutex& m_mutex; +}; -class noop_mutex final - { +class noop_mutex final { public: - void lock() {} - void unlock() {} - }; + void lock() {} + void unlock() {} +}; typedef noop_mutex mutex_type; -template using lock_guard_type = lock_guard; +template +using lock_guard_type = lock_guard; -} +} // namespace Botan #endif @@ -7469,339 +6826,317 @@ namespace Botan { class Entropy_Sources; /** -* An interface to a cryptographic random number generator -*/ -class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator - { + * An interface to a cryptographic random number generator + */ +class BOTAN_PUBLIC_API(2, 0) RandomNumberGenerator { public: - virtual ~RandomNumberGenerator() = default; + virtual ~RandomNumberGenerator() = default; - RandomNumberGenerator() = default; + RandomNumberGenerator() = default; - /* - * Never copy a RNG, create a new one - */ - RandomNumberGenerator(const RandomNumberGenerator& rng) = delete; - RandomNumberGenerator& operator=(const RandomNumberGenerator& rng) = delete; + /* + * Never copy a RNG, create a new one + */ + RandomNumberGenerator(const RandomNumberGenerator& rng) = delete; + RandomNumberGenerator& operator=(const RandomNumberGenerator& rng) = delete; - /** - * Randomize a byte array. - * @param output the byte array to hold the random output. - * @param length the length of the byte array output in bytes. - */ - virtual void randomize(uint8_t output[], size_t length) = 0; + /** + * Randomize a byte array. + * @param output the byte array to hold the random output. + * @param length the length of the byte array output in bytes. + */ + virtual void randomize(uint8_t output[], size_t length) = 0; - /** - * Returns false if it is known that this RNG object is not able to accept - * externally provided inputs (via add_entropy, randomize_with_input, etc). - * In this case, any such provided inputs are ignored. - * - * If this function returns true, then inputs may or may not be accepted. - */ - virtual bool accepts_input() const = 0; + /** + * Returns false if it is known that this RNG object is not able to accept + * externally provided inputs (via add_entropy, randomize_with_input, etc). + * In this case, any such provided inputs are ignored. + * + * If this function returns true, then inputs may or may not be accepted. + */ + virtual bool accepts_input() const = 0; - /** - * Incorporate some additional data into the RNG state. For - * example adding nonces or timestamps from a peer's protocol - * message can help hedge against VM state rollback attacks. - * A few RNG types do not accept any externally provided input, - * in which case this function is a no-op. - * - * @param input a byte array containg the entropy to be added - * @param length the length of the byte array in - */ - virtual void add_entropy(const uint8_t input[], size_t length) = 0; + /** + * Incorporate some additional data into the RNG state. For + * example adding nonces or timestamps from a peer's protocol + * message can help hedge against VM state rollback attacks. + * A few RNG types do not accept any externally provided input, + * in which case this function is a no-op. + * + * @param input a byte array containg the entropy to be added + * @param length the length of the byte array in + */ + virtual void add_entropy(const uint8_t input[], size_t length) = 0; - /** - * Incorporate some additional data into the RNG state. - */ - template void add_entropy_T(const T& t) - { - this->add_entropy(reinterpret_cast(&t), sizeof(T)); - } + /** + * Incorporate some additional data into the RNG state. + */ + template + void add_entropy_T(const T& t) { + this->add_entropy(reinterpret_cast(&t), sizeof(T)); + } - /** - * Incorporate entropy into the RNG state then produce output. - * Some RNG types implement this using a single operation, default - * calls add_entropy + randomize in sequence. - * - * Use this to further bind the outputs to your current - * process/protocol state. For instance if generating a new key - * for use in a session, include a session ID or other such - * value. See NIST SP 800-90 A, B, C series for more ideas. - * - * @param output buffer to hold the random output - * @param output_len size of the output buffer in bytes - * @param input entropy buffer to incorporate - * @param input_len size of the input buffer in bytes - */ - virtual void randomize_with_input(uint8_t output[], size_t output_len, - const uint8_t input[], size_t input_len); + /** + * Incorporate entropy into the RNG state then produce output. + * Some RNG types implement this using a single operation, default + * calls add_entropy + randomize in sequence. + * + * Use this to further bind the outputs to your current + * process/protocol state. For instance if generating a new key + * for use in a session, include a session ID or other such + * value. See NIST SP 800-90 A, B, C series for more ideas. + * + * @param output buffer to hold the random output + * @param output_len size of the output buffer in bytes + * @param input entropy buffer to incorporate + * @param input_len size of the input buffer in bytes + */ + virtual void randomize_with_input(uint8_t output[], size_t output_len, const uint8_t input[], + size_t input_len); - /** - * This calls `randomize_with_input` using some timestamps as extra input. - * - * For a stateful RNG using non-random but potentially unique data the - * extra input can help protect against problems with fork, VM state - * rollback, or other cases where somehow an RNG state is duplicated. If - * both of the duplicated RNG states later incorporate a timestamp (and the - * timestamps don't themselves repeat), their outputs will diverge. - */ - virtual void randomize_with_ts_input(uint8_t output[], size_t output_len); + /** + * This calls `randomize_with_input` using some timestamps as extra input. + * + * For a stateful RNG using non-random but potentially unique data the + * extra input can help protect against problems with fork, VM state + * rollback, or other cases where somehow an RNG state is duplicated. If + * both of the duplicated RNG states later incorporate a timestamp (and the + * timestamps don't themselves repeat), their outputs will diverge. + */ + virtual void randomize_with_ts_input(uint8_t output[], size_t output_len); - /** - * @return the name of this RNG type - */ - virtual std::string name() const = 0; + /** + * @return the name of this RNG type + */ + virtual std::string name() const = 0; - /** - * Clear all internally held values of this RNG - * @post is_seeded() == false - */ - virtual void clear() = 0; + /** + * Clear all internally held values of this RNG + * @post is_seeded() == false + */ + virtual void clear() = 0; - /** - * Check whether this RNG is seeded. - * @return true if this RNG was already seeded, false otherwise. - */ - virtual bool is_seeded() const = 0; + /** + * Check whether this RNG is seeded. + * @return true if this RNG was already seeded, false otherwise. + */ + virtual bool is_seeded() const = 0; - /** - * Poll provided sources for up to poll_bits bits of entropy - * or until the timeout expires. Returns estimate of the number - * of bits collected. - */ - virtual size_t reseed(Entropy_Sources& srcs, - size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, - std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT); + /** + * Poll provided sources for up to poll_bits bits of entropy + * or until the timeout expires. Returns estimate of the number + * of bits collected. + */ + virtual size_t reseed( + Entropy_Sources& srcs, size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT); - /** - * Reseed by reading specified bits from the RNG - */ - virtual void reseed_from_rng(RandomNumberGenerator& rng, - size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS); + /** + * Reseed by reading specified bits from the RNG + */ + virtual void reseed_from_rng(RandomNumberGenerator& rng, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS); - // Some utility functions built on the interface above: + // Some utility functions built on the interface above: - /** - * Return a random vector - * @param bytes number of bytes in the result - * @return randomized vector of length bytes - */ - secure_vector random_vec(size_t bytes) - { - secure_vector output; - random_vec(output, bytes); - return output; - } + /** + * Return a random vector + * @param bytes number of bytes in the result + * @return randomized vector of length bytes + */ + secure_vector random_vec(size_t bytes) { + secure_vector output; + random_vec(output, bytes); + return output; + } - template - void random_vec(std::vector& v, size_t bytes) - { - v.resize(bytes); - this->randomize(v.data(), v.size()); - } + template + void random_vec(std::vector& v, size_t bytes) { + v.resize(bytes); + this->randomize(v.data(), v.size()); + } - /** - * Return a random byte - * @return random byte - */ - uint8_t next_byte() - { - uint8_t b; - this->randomize(&b, 1); - return b; - } + /** + * Return a random byte + * @return random byte + */ + uint8_t next_byte() { + uint8_t b; + this->randomize(&b, 1); + return b; + } - /** - * @return a random byte that is greater than zero - */ - uint8_t next_nonzero_byte() - { - uint8_t b = this->next_byte(); - while(b == 0) - b = this->next_byte(); - return b; - } + /** + * @return a random byte that is greater than zero + */ + uint8_t next_nonzero_byte() { + uint8_t b = this->next_byte(); + while (b == 0) b = this->next_byte(); + return b; + } - /** - * Create a seeded and active RNG object for general application use - * Added in 1.8.0 - * Use AutoSeeded_RNG instead - */ - BOTAN_DEPRECATED("Use AutoSeeded_RNG") - static RandomNumberGenerator* make_rng(); - }; + /** + * Create a seeded and active RNG object for general application use + * Added in 1.8.0 + * Use AutoSeeded_RNG instead + */ + BOTAN_DEPRECATED("Use AutoSeeded_RNG") + static RandomNumberGenerator* make_rng(); +}; /** -* Convenience typedef -*/ + * Convenience typedef + */ typedef RandomNumberGenerator RNG; /** -* Hardware_RNG exists to tag hardware RNG types (PKCS11_RNG, TPM_RNG, RDRAND_RNG) -*/ -class BOTAN_PUBLIC_API(2,0) Hardware_RNG : public RandomNumberGenerator - { + * Hardware_RNG exists to tag hardware RNG types (PKCS11_RNG, TPM_RNG, RDRAND_RNG) + */ +class BOTAN_PUBLIC_API(2, 0) Hardware_RNG : public RandomNumberGenerator { public: - virtual void clear() final override { /* no way to clear state of hardware RNG */ } - }; + virtual void clear() final override { /* no way to clear state of hardware RNG */ } +}; /** -* Null/stub RNG - fails if you try to use it for anything -* This is not generally useful except for in certain tests -*/ -class BOTAN_PUBLIC_API(2,0) Null_RNG final : public RandomNumberGenerator - { + * Null/stub RNG - fails if you try to use it for anything + * This is not generally useful except for in certain tests + */ +class BOTAN_PUBLIC_API(2, 0) Null_RNG final : public RandomNumberGenerator { public: - bool is_seeded() const override { return false; } + bool is_seeded() const override { return false; } - bool accepts_input() const override { return false; } + bool accepts_input() const override { return false; } - void clear() override {} + void clear() override {} - void randomize(uint8_t[], size_t) override - { - throw PRNG_Unseeded("Null_RNG called"); - } + void randomize(uint8_t[], size_t) override { throw PRNG_Unseeded("Null_RNG called"); } - void add_entropy(const uint8_t[], size_t) override {} + void add_entropy(const uint8_t[], size_t) override {} - std::string name() const override { return "Null_RNG"; } - }; + std::string name() const override { return "Null_RNG"; } +}; #if defined(BOTAN_TARGET_OS_HAS_THREADS) /** -* Wraps access to a RNG in a mutex -* Note that most of the time it's much better to use a RNG per thread -* otherwise the RNG will act as an unnecessary contention point -*/ -class BOTAN_PUBLIC_API(2,0) Serialized_RNG final : public RandomNumberGenerator - { + * Wraps access to a RNG in a mutex + * Note that most of the time it's much better to use a RNG per thread + * otherwise the RNG will act as an unnecessary contention point + */ +class BOTAN_PUBLIC_API(2, 0) Serialized_RNG final : public RandomNumberGenerator { public: - void randomize(uint8_t out[], size_t len) override - { - lock_guard_type lock(m_mutex); - m_rng->randomize(out, len); - } + void randomize(uint8_t out[], size_t len) override { + lock_guard_type lock(m_mutex); + m_rng->randomize(out, len); + } - bool accepts_input() const override - { - lock_guard_type lock(m_mutex); - return m_rng->accepts_input(); - } + bool accepts_input() const override { + lock_guard_type lock(m_mutex); + return m_rng->accepts_input(); + } - bool is_seeded() const override - { - lock_guard_type lock(m_mutex); - return m_rng->is_seeded(); - } + bool is_seeded() const override { + lock_guard_type lock(m_mutex); + return m_rng->is_seeded(); + } - void clear() override - { - lock_guard_type lock(m_mutex); - m_rng->clear(); - } + void clear() override { + lock_guard_type lock(m_mutex); + m_rng->clear(); + } - std::string name() const override - { - lock_guard_type lock(m_mutex); - return m_rng->name(); - } + std::string name() const override { + lock_guard_type lock(m_mutex); + return m_rng->name(); + } - size_t reseed(Entropy_Sources& src, - size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, - std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override - { - lock_guard_type lock(m_mutex); - return m_rng->reseed(src, poll_bits, poll_timeout); - } + size_t reseed( + Entropy_Sources& src, size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override { + lock_guard_type lock(m_mutex); + return m_rng->reseed(src, poll_bits, poll_timeout); + } - void add_entropy(const uint8_t in[], size_t len) override - { - lock_guard_type lock(m_mutex); - m_rng->add_entropy(in, len); - } + void add_entropy(const uint8_t in[], size_t len) override { + lock_guard_type lock(m_mutex); + m_rng->add_entropy(in, len); + } - BOTAN_DEPRECATED("Use Serialized_RNG(new AutoSeeded_RNG)") Serialized_RNG(); + BOTAN_DEPRECATED("Use Serialized_RNG(new AutoSeeded_RNG)") Serialized_RNG(); + + explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {} - explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {} private: - mutable mutex_type m_mutex; - std::unique_ptr m_rng; - }; + mutable mutex_type m_mutex; + std::unique_ptr m_rng; +}; #endif -} +} // namespace Botan namespace Botan { class RandomNumberGenerator; /** -* Abstract interface to a source of entropy -*/ -class BOTAN_PUBLIC_API(2,0) Entropy_Source - { + * Abstract interface to a source of entropy + */ +class BOTAN_PUBLIC_API(2, 0) Entropy_Source { public: - /** - * Return a new entropy source of a particular type, or null - * Each entropy source may require substantial resources (eg, a file handle - * or socket instance), so try to share them among multiple RNGs, or just - * use the preconfigured global list accessed by Entropy_Sources::global_sources() - */ - static std::unique_ptr create(const std::string& type); + /** + * Return a new entropy source of a particular type, or null + * Each entropy source may require substantial resources (eg, a file handle + * or socket instance), so try to share them among multiple RNGs, or just + * use the preconfigured global list accessed by Entropy_Sources::global_sources() + */ + static std::unique_ptr create(const std::string& type); - /** - * @return name identifying this entropy source - */ - virtual std::string name() const = 0; + /** + * @return name identifying this entropy source + */ + virtual std::string name() const = 0; - /** - * Perform an entropy gathering poll - * @param rng will be provided with entropy via calls to add_entropy - * @return conservative estimate of actual entropy added to rng during poll - */ - virtual size_t poll(RandomNumberGenerator& rng) = 0; + /** + * Perform an entropy gathering poll + * @param rng will be provided with entropy via calls to add_entropy + * @return conservative estimate of actual entropy added to rng during poll + */ + virtual size_t poll(RandomNumberGenerator& rng) = 0; - Entropy_Source() = default; - Entropy_Source(const Entropy_Source& other) = delete; - Entropy_Source(Entropy_Source&& other) = delete; - Entropy_Source& operator=(const Entropy_Source& other) = delete; + Entropy_Source() = default; + Entropy_Source(const Entropy_Source& other) = delete; + Entropy_Source(Entropy_Source&& other) = delete; + Entropy_Source& operator=(const Entropy_Source& other) = delete; - virtual ~Entropy_Source() = default; - }; + virtual ~Entropy_Source() = default; +}; -class BOTAN_PUBLIC_API(2,0) Entropy_Sources final - { +class BOTAN_PUBLIC_API(2, 0) Entropy_Sources final { public: - static Entropy_Sources& global_sources(); + static Entropy_Sources& global_sources(); - void add_source(std::unique_ptr src); + void add_source(std::unique_ptr src); - std::vector enabled_sources() const; + std::vector enabled_sources() const; - size_t poll(RandomNumberGenerator& rng, - size_t bits, - std::chrono::milliseconds timeout); + size_t poll(RandomNumberGenerator& rng, size_t bits, std::chrono::milliseconds timeout); - /** - * Poll just a single named source. Ordinally only used for testing - */ - size_t poll_just(RandomNumberGenerator& rng, const std::string& src); + /** + * Poll just a single named source. Ordinally only used for testing + */ + size_t poll_just(RandomNumberGenerator& rng, const std::string& src); - Entropy_Sources() = default; - explicit Entropy_Sources(const std::vector& sources); + Entropy_Sources() = default; + explicit Entropy_Sources(const std::vector& sources); - Entropy_Sources(const Entropy_Sources& other) = delete; - Entropy_Sources(Entropy_Sources&& other) = delete; - Entropy_Sources& operator=(const Entropy_Sources& other) = delete; + Entropy_Sources(const Entropy_Sources& other) = delete; + Entropy_Sources(Entropy_Sources&& other) = delete; + Entropy_Sources& operator=(const Entropy_Sources& other) = delete; private: - std::vector> m_srcs; - }; + std::vector> m_srcs; +}; -} +} // namespace Botan namespace Botan { @@ -7809,363 +7144,359 @@ class Filter; class Output_Buffers; /** -* This class represents pipe objects. -* A set of filters can be placed into a pipe, and information flows -* through the pipe until it reaches the end, where the output is -* collected for retrieval. If you're familiar with the Unix shell -* environment, this design will sound quite familiar. -*/ -class BOTAN_PUBLIC_API(2,0) Pipe final : public DataSource - { + * This class represents pipe objects. + * A set of filters can be placed into a pipe, and information flows + * through the pipe until it reaches the end, where the output is + * collected for retrieval. If you're familiar with the Unix shell + * environment, this design will sound quite familiar. + */ +class BOTAN_PUBLIC_API(2, 0) Pipe final : public DataSource { public: - /** - * An opaque type that identifies a message in this Pipe - */ - typedef size_t message_id; + /** + * An opaque type that identifies a message in this Pipe + */ + typedef size_t message_id; - /** - * Exception if you use an invalid message as an argument to - * read, remaining, etc - */ - class BOTAN_PUBLIC_API(2,0) Invalid_Message_Number final : public Invalid_Argument - { - public: - /** - * @param where the error occurred - * @param msg the invalid message id that was used - */ - Invalid_Message_Number(const std::string& where, message_id msg) : - Invalid_Argument("Pipe::" + where + ": Invalid message number " + - std::to_string(msg)) - {} - }; + /** + * Exception if you use an invalid message as an argument to + * read, remaining, etc + */ + class BOTAN_PUBLIC_API(2, 0) Invalid_Message_Number final : public Invalid_Argument { + public: + /** + * @param where the error occurred + * @param msg the invalid message id that was used + */ + Invalid_Message_Number(const std::string& where, message_id msg) + : Invalid_Argument("Pipe::" + where + ": Invalid message number " + + std::to_string(msg)) {} + }; - /** - * A meta-id for whatever the last message is - */ - static const message_id LAST_MESSAGE; + /** + * A meta-id for whatever the last message is + */ + static const message_id LAST_MESSAGE; - /** - * A meta-id for the default message (set with set_default_msg) - */ - static const message_id DEFAULT_MESSAGE; + /** + * A meta-id for the default message (set with set_default_msg) + */ + static const message_id DEFAULT_MESSAGE; - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the byte array to write - * @param length the length of the byte array in - */ - void write(const uint8_t in[], size_t length); + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the byte array to write + * @param length the length of the byte array in + */ + void write(const uint8_t in[], size_t length); - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the secure_vector containing the data to write - */ - void write(const secure_vector& in) - { write(in.data(), in.size()); } + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the secure_vector containing the data to write + */ + void write(const secure_vector& in) { write(in.data(), in.size()); } - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the std::vector containing the data to write - */ - void write(const std::vector& in) - { write(in.data(), in.size()); } + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the std::vector containing the data to write + */ + void write(const std::vector& in) { write(in.data(), in.size()); } - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the string containing the data to write - */ - void write(const std::string& in); + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the string containing the data to write + */ + void write(const std::string& in); - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the DataSource to read the data from - */ - void write(DataSource& in); + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the DataSource to read the data from + */ + void write(DataSource& in); - /** - * Write input to the pipe, i.e. to its first filter. - * @param in a single byte to be written - */ - void write(uint8_t in); + /** + * Write input to the pipe, i.e. to its first filter. + * @param in a single byte to be written + */ + void write(uint8_t in); - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the byte array containing the data to write - * @param length the length of the byte array to write - */ - void process_msg(const uint8_t in[], size_t length); + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the byte array containing the data to write + * @param length the length of the byte array to write + */ + void process_msg(const uint8_t in[], size_t length); - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the secure_vector containing the data to write - */ - void process_msg(const secure_vector& in); + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the secure_vector containing the data to write + */ + void process_msg(const secure_vector& in); - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the secure_vector containing the data to write - */ - void process_msg(const std::vector& in); + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the secure_vector containing the data to write + */ + void process_msg(const std::vector& in); - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the string containing the data to write - */ - void process_msg(const std::string& in); + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the string containing the data to write + */ + void process_msg(const std::string& in); - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the DataSource providing the data to write - */ - void process_msg(DataSource& in); + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the DataSource providing the data to write + */ + void process_msg(DataSource& in); - /** - * Find out how many bytes are ready to read. - * @param msg the number identifying the message - * for which the information is desired - * @return number of bytes that can still be read - */ - size_t remaining(message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT; + /** + * Find out how many bytes are ready to read. + * @param msg the number identifying the message + * for which the information is desired + * @return number of bytes that can still be read + */ + size_t remaining(message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT; - /** - * Read the default message from the pipe. Moves the internal - * offset so that every call to read will return a new portion of - * the message. - * - * @param output the byte array to write the read bytes to - * @param length the length of the byte array output - * @return number of bytes actually read into output - */ - size_t read(uint8_t output[], size_t length) override BOTAN_WARN_UNUSED_RESULT; + /** + * Read the default message from the pipe. Moves the internal + * offset so that every call to read will return a new portion of + * the message. + * + * @param output the byte array to write the read bytes to + * @param length the length of the byte array output + * @return number of bytes actually read into output + */ + size_t read(uint8_t output[], size_t length) override BOTAN_WARN_UNUSED_RESULT; - /** - * Read a specified message from the pipe. Moves the internal - * offset so that every call to read will return a new portion of - * the message. - * @param output the byte array to write the read bytes to - * @param length the length of the byte array output - * @param msg the number identifying the message to read from - * @return number of bytes actually read into output - */ - size_t read(uint8_t output[], size_t length, message_id msg) BOTAN_WARN_UNUSED_RESULT; + /** + * Read a specified message from the pipe. Moves the internal + * offset so that every call to read will return a new portion of + * the message. + * @param output the byte array to write the read bytes to + * @param length the length of the byte array output + * @param msg the number identifying the message to read from + * @return number of bytes actually read into output + */ + size_t read(uint8_t output[], size_t length, message_id msg) BOTAN_WARN_UNUSED_RESULT; - /** - * Read a single byte from the pipe. Moves the internal offset so - * that every call to read will return a new portion of the - * message. - * - * @param output the byte to write the result to - * @param msg the message to read from - * @return number of bytes actually read into output - */ - size_t read(uint8_t& output, message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; + /** + * Read a single byte from the pipe. Moves the internal offset so + * that every call to read will return a new portion of the + * message. + * + * @param output the byte to write the result to + * @param msg the message to read from + * @return number of bytes actually read into output + */ + size_t read(uint8_t& output, message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; - /** - * Read the full contents of the pipe. - * @param msg the number identifying the message to read from - * @return secure_vector holding the contents of the pipe - */ - secure_vector read_all(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; + /** + * Read the full contents of the pipe. + * @param msg the number identifying the message to read from + * @return secure_vector holding the contents of the pipe + */ + secure_vector read_all(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; - /** - * Read the full contents of the pipe. - * @param msg the number identifying the message to read from - * @return string holding the contents of the pipe - */ - std::string read_all_as_string(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; + /** + * Read the full contents of the pipe. + * @param msg the number identifying the message to read from + * @return string holding the contents of the pipe + */ + std::string read_all_as_string(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; - /** - * Read from the default message but do not modify the internal - * offset. Consecutive calls to peek() will return portions of - * the message starting at the same position. - * @param output the byte array to write the peeked message part to - * @param length the length of the byte array output - * @param offset the offset from the current position in message - * @return number of bytes actually peeked and written into output - */ - size_t peek(uint8_t output[], size_t length, size_t offset) const override BOTAN_WARN_UNUSED_RESULT; + /** + * Read from the default message but do not modify the internal + * offset. Consecutive calls to peek() will return portions of + * the message starting at the same position. + * @param output the byte array to write the peeked message part to + * @param length the length of the byte array output + * @param offset the offset from the current position in message + * @return number of bytes actually peeked and written into output + */ + size_t peek(uint8_t output[], size_t length, + size_t offset) const override BOTAN_WARN_UNUSED_RESULT; - /** Read from the specified message but do not modify the - * internal offset. Consecutive calls to peek() will return - * portions of the message starting at the same position. - * @param output the byte array to write the peeked message part to - * @param length the length of the byte array output - * @param offset the offset from the current position in message - * @param msg the number identifying the message to peek from - * @return number of bytes actually peeked and written into output - */ - size_t peek(uint8_t output[], size_t length, - size_t offset, message_id msg) const BOTAN_WARN_UNUSED_RESULT; + /** Read from the specified message but do not modify the + * internal offset. Consecutive calls to peek() will return + * portions of the message starting at the same position. + * @param output the byte array to write the peeked message part to + * @param length the length of the byte array output + * @param offset the offset from the current position in message + * @param msg the number identifying the message to peek from + * @return number of bytes actually peeked and written into output + */ + size_t peek(uint8_t output[], size_t length, size_t offset, + message_id msg) const BOTAN_WARN_UNUSED_RESULT; - /** Read a single byte from the specified message but do not - * modify the internal offset. Consecutive calls to peek() will - * return portions of the message starting at the same position. - * @param output the byte to write the peeked message byte to - * @param offset the offset from the current position in message - * @param msg the number identifying the message to peek from - * @return number of bytes actually peeked and written into output - */ - size_t peek(uint8_t& output, size_t offset, - message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT; + /** Read a single byte from the specified message but do not + * modify the internal offset. Consecutive calls to peek() will + * return portions of the message starting at the same position. + * @param output the byte to write the peeked message byte to + * @param offset the offset from the current position in message + * @param msg the number identifying the message to peek from + * @return number of bytes actually peeked and written into output + */ + size_t peek(uint8_t& output, size_t offset, + message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT; - /** - * @return the number of bytes read from the default message. - */ - size_t get_bytes_read() const override; + /** + * @return the number of bytes read from the default message. + */ + size_t get_bytes_read() const override; - /** - * @return the number of bytes read from the specified message. - */ - size_t get_bytes_read(message_id msg) const; + /** + * @return the number of bytes read from the specified message. + */ + size_t get_bytes_read(message_id msg) const; - bool check_available(size_t n) override; - bool check_available_msg(size_t n, message_id msg); + bool check_available(size_t n) override; + bool check_available_msg(size_t n, message_id msg); - /** - * @return currently set default message - */ - size_t default_msg() const { return m_default_read; } + /** + * @return currently set default message + */ + size_t default_msg() const { return m_default_read; } - /** - * Set the default message - * @param msg the number identifying the message which is going to - * be the new default message - */ - void set_default_msg(message_id msg); + /** + * Set the default message + * @param msg the number identifying the message which is going to + * be the new default message + */ + void set_default_msg(message_id msg); - /** - * Get the number of messages the are in this pipe. - * @return number of messages the are in this pipe - */ - message_id message_count() const; + /** + * Get the number of messages the are in this pipe. + * @return number of messages the are in this pipe + */ + message_id message_count() const; - /** - * Test whether this pipe has any data that can be read from. - * @return true if there is more data to read, false otherwise - */ - bool end_of_data() const override; + /** + * Test whether this pipe has any data that can be read from. + * @return true if there is more data to read, false otherwise + */ + bool end_of_data() const override; - /** - * Start a new message in the pipe. A potential other message in this pipe - * must be closed with end_msg() before this function may be called. - */ - void start_msg(); + /** + * Start a new message in the pipe. A potential other message in this pipe + * must be closed with end_msg() before this function may be called. + */ + void start_msg(); - /** - * End the current message. - */ - void end_msg(); + /** + * End the current message. + */ + void end_msg(); - /** - * Insert a new filter at the front of the pipe - * Deprecated because runtime modification of Pipes is deprecated. - * You can instead use prepend_filter which only works before the first - * message is processed. - * @param filt the new filter to insert - */ - BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") - void prepend(Filter* filt); + /** + * Insert a new filter at the front of the pipe + * Deprecated because runtime modification of Pipes is deprecated. + * You can instead use prepend_filter which only works before the first + * message is processed. + * @param filt the new filter to insert + */ + BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") + void prepend(Filter* filt); - /** - * Insert a new filter at the back of the pipe - * Deprecated because runtime modification of Pipes is deprecated. - * You can instead use append_filter which only works before the first - * message is processed. - * @param filt the new filter to insert - */ - BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") - void append(Filter* filt); + /** + * Insert a new filter at the back of the pipe + * Deprecated because runtime modification of Pipes is deprecated. + * You can instead use append_filter which only works before the first + * message is processed. + * @param filt the new filter to insert + */ + BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") + void append(Filter* filt); - /** - * Remove the first filter at the front of the pipe. - */ - BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") - void pop(); + /** + * Remove the first filter at the front of the pipe. + */ + BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") + void pop(); - /** - * Reset this pipe to an empty pipe. - */ - BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") - void reset(); + /** + * Reset this pipe to an empty pipe. + */ + BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") + void reset(); - /** - * Append a new filter onto the filter sequence. This may only be - * called immediately after initial construction, before _any_ - * calls to start_msg have been made. - * - * This function (unlike append) is not deprecated, as it allows - * only modification of the pipe at initialization (before use) - * rather than after messages have been processed. - */ - void append_filter(Filter* filt); + /** + * Append a new filter onto the filter sequence. This may only be + * called immediately after initial construction, before _any_ + * calls to start_msg have been made. + * + * This function (unlike append) is not deprecated, as it allows + * only modification of the pipe at initialization (before use) + * rather than after messages have been processed. + */ + void append_filter(Filter* filt); - /** - * Prepend a new filter onto the filter sequence. This may only be - * called immediately after initial construction, before _any_ - * calls to start_msg have been made. - * - * This function (unlike prepend) is not deprecated, as it allows - * only modification of the pipe at initialization (before use) - * rather than after messages have been processed. - */ - void prepend_filter(Filter* filt); + /** + * Prepend a new filter onto the filter sequence. This may only be + * called immediately after initial construction, before _any_ + * calls to start_msg have been made. + * + * This function (unlike prepend) is not deprecated, as it allows + * only modification of the pipe at initialization (before use) + * rather than after messages have been processed. + */ + void prepend_filter(Filter* filt); - /** - * Construct a Pipe of up to four filters. The filters are set up - * in the same order as the arguments. - */ - Pipe(Filter* = nullptr, Filter* = nullptr, - Filter* = nullptr, Filter* = nullptr); + /** + * Construct a Pipe of up to four filters. The filters are set up + * in the same order as the arguments. + */ + Pipe(Filter* = nullptr, Filter* = nullptr, Filter* = nullptr, Filter* = nullptr); - /** - * Construct a Pipe from a list of filters - * @param filters the set of filters to use - */ - explicit Pipe(std::initializer_list filters); + /** + * Construct a Pipe from a list of filters + * @param filters the set of filters to use + */ + explicit Pipe(std::initializer_list filters); - Pipe(const Pipe&) = delete; - Pipe& operator=(const Pipe&) = delete; + Pipe(const Pipe&) = delete; + Pipe& operator=(const Pipe&) = delete; + + ~Pipe(); - ~Pipe(); private: - void destruct(Filter*); - void do_append(Filter* filt); - void do_prepend(Filter* filt); - void find_endpoints(Filter*); - void clear_endpoints(Filter*); + void destruct(Filter*); + void do_append(Filter* filt); + void do_prepend(Filter* filt); + void find_endpoints(Filter*); + void clear_endpoints(Filter*); - message_id get_message_no(const std::string&, message_id) const; + message_id get_message_no(const std::string&, message_id) const; - Filter* m_pipe; - std::unique_ptr m_outputs; - message_id m_default_read; - bool m_inside_msg; - }; + Filter* m_pipe; + std::unique_ptr m_outputs; + message_id m_default_read; + bool m_inside_msg; +}; /** -* Stream output operator; dumps the results from pipe's default -* message to the output stream. -* @param out an output stream -* @param pipe the pipe -*/ -BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, Pipe& pipe); + * Stream output operator; dumps the results from pipe's default + * message to the output stream. + * @param out an output stream + * @param pipe the pipe + */ +BOTAN_PUBLIC_API(2, 0) std::ostream& operator<<(std::ostream& out, Pipe& pipe); /** -* Stream input operator; dumps the remaining bytes of input -* to the (assumed open) pipe message. -* @param in the input stream -* @param pipe the pipe -*/ -BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, Pipe& pipe); + * Stream input operator; dumps the remaining bytes of input + * to the (assumed open) pipe message. + * @param in the input stream + * @param pipe the pipe + */ +BOTAN_PUBLIC_API(2, 0) std::istream& operator>>(std::istream& in, Pipe& pipe); -} +} // namespace Botan #if defined(BOTAN_HAS_PIPE_UNIXFD_IO) #endif #if defined(BOTAN_TARGET_OS_HAS_THREADS) - #include +#include #endif #if defined(BOTAN_HAS_STREAM_CIPHER) @@ -8176,78 +7507,75 @@ BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, Pipe& pipe); namespace Botan { /** -* This class represents hash function (message digest) objects -*/ -class BOTAN_PUBLIC_API(2,0) HashFunction : public Buffered_Computation - { + * This class represents hash function (message digest) objects + */ +class BOTAN_PUBLIC_API(2, 0) HashFunction : public Buffered_Computation { public: - /** - * Create an instance based on a name, or return null if the - * algo/provider combination cannot be found. If provider is - * empty then best available is chosen. - */ - static std::unique_ptr - create(const std::string& algo_spec, - const std::string& provider = ""); + /** + * Create an instance based on a name, or return null if the + * algo/provider combination cannot be found. If provider is + * empty then best available is chosen. + */ + static std::unique_ptr create(const std::string& algo_spec, + const std::string& provider = ""); - /** - * Create an instance based on a name - * If provider is empty then best available is chosen. - * @param algo_spec algorithm name - * @param provider provider implementation to use - * Throws Lookup_Error if not found. - */ - static std::unique_ptr - create_or_throw(const std::string& algo_spec, - const std::string& provider = ""); + /** + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to use + * Throws Lookup_Error if not found. + */ + static std::unique_ptr create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); - /** - * @return list of available providers for this algorithm, empty if not available - * @param algo_spec algorithm name - */ - static std::vector providers(const std::string& algo_spec); + /** + * @return list of available providers for this algorithm, empty if not available + * @param algo_spec algorithm name + */ + static std::vector providers(const std::string& algo_spec); - /** - * @return new object representing the same algorithm as *this - */ - virtual HashFunction* clone() const = 0; + /** + * @return new object representing the same algorithm as *this + */ + virtual HashFunction* clone() const = 0; - /** - * @return provider information about this implementation. Default is "base", - * might also return "sse2", "avx2", "openssl", or some other arbitrary string. - */ - virtual std::string provider() const { return "base"; } + /** + * @return provider information about this implementation. Default is "base", + * might also return "sse2", "avx2", "openssl", or some other arbitrary string. + */ + virtual std::string provider() const { return "base"; } - virtual ~HashFunction() = default; + virtual ~HashFunction() = default; - /** - * Reset the state. - */ - virtual void clear() = 0; + /** + * Reset the state. + */ + virtual void clear() = 0; - /** - * @return the hash function name - */ - virtual std::string name() const = 0; + /** + * @return the hash function name + */ + virtual std::string name() const = 0; - /** - * @return hash block size as defined for this algorithm - */ - virtual size_t hash_block_size() const { return 0; } + /** + * @return hash block size as defined for this algorithm + */ + virtual size_t hash_block_size() const { return 0; } - /** - * Return a new hash object with the same state as *this. This - * allows computing the hash of several messages with a common - * prefix more efficiently than would otherwise be possible. - * - * This function should be called `clone` but that was already - * used for the case of returning an uninitialized object. - * @return new hash object - */ - virtual std::unique_ptr copy_state() const = 0; - }; + /** + * Return a new hash object with the same state as *this. This + * allows computing the hash of several messages with a common + * prefix more efficiently than would otherwise be possible. + * + * This function should be called `clone` but that was already + * used for the case of returning an uninitialized object. + * @return new hash object + */ + virtual std::unique_ptr copy_state() const = 0; +}; -} +} // namespace Botan #endif #if defined(BOTAN_HAS_MAC) @@ -8256,415 +7584,384 @@ class BOTAN_PUBLIC_API(2,0) HashFunction : public Buffered_Computation namespace Botan { /** -* Filter mixin that breaks input into blocks, useful for -* cipher modes -*/ -class BOTAN_PUBLIC_API(2,0) Buffered_Filter - { + * Filter mixin that breaks input into blocks, useful for + * cipher modes + */ +class BOTAN_PUBLIC_API(2, 0) Buffered_Filter { public: - /** - * Write bytes into the buffered filter, which will them emit them - * in calls to buffered_block in the subclass - * @param in the input bytes - * @param length of in in bytes - */ - void write(const uint8_t in[], size_t length); + /** + * Write bytes into the buffered filter, which will them emit them + * in calls to buffered_block in the subclass + * @param in the input bytes + * @param length of in in bytes + */ + void write(const uint8_t in[], size_t length); - template - void write(const std::vector& in, size_t length) - { - write(in.data(), length); - } + template + void write(const std::vector& in, size_t length) { + write(in.data(), length); + } - /** - * Finish a message, emitting to buffered_block and buffered_final - * Will throw an exception if less than final_minimum bytes were - * written into the filter. - */ - void end_msg(); + /** + * Finish a message, emitting to buffered_block and buffered_final + * Will throw an exception if less than final_minimum bytes were + * written into the filter. + */ + void end_msg(); - /** - * Initialize a Buffered_Filter - * @param block_size the function buffered_block will be called - * with inputs which are a multiple of this size - * @param final_minimum the function buffered_final will be called - * with at least this many bytes. - */ - Buffered_Filter(size_t block_size, size_t final_minimum); + /** + * Initialize a Buffered_Filter + * @param block_size the function buffered_block will be called + * with inputs which are a multiple of this size + * @param final_minimum the function buffered_final will be called + * with at least this many bytes. + */ + Buffered_Filter(size_t block_size, size_t final_minimum); + + virtual ~Buffered_Filter() = default; - virtual ~Buffered_Filter() = default; protected: - /** - * The block processor, implemented by subclasses - * @param input some input bytes - * @param length the size of input, guaranteed to be a multiple - * of block_size - */ - virtual void buffered_block(const uint8_t input[], size_t length) = 0; + /** + * The block processor, implemented by subclasses + * @param input some input bytes + * @param length the size of input, guaranteed to be a multiple + * of block_size + */ + virtual void buffered_block(const uint8_t input[], size_t length) = 0; - /** - * The final block, implemented by subclasses - * @param input some input bytes - * @param length the size of input, guaranteed to be at least - * final_minimum bytes - */ - virtual void buffered_final(const uint8_t input[], size_t length) = 0; + /** + * The final block, implemented by subclasses + * @param input some input bytes + * @param length the size of input, guaranteed to be at least + * final_minimum bytes + */ + virtual void buffered_final(const uint8_t input[], size_t length) = 0; - /** - * @return block size of inputs - */ - size_t buffered_block_size() const { return m_main_block_mod; } + /** + * @return block size of inputs + */ + size_t buffered_block_size() const { return m_main_block_mod; } - /** - * @return current position in the buffer - */ - size_t current_position() const { return m_buffer_pos; } + /** + * @return current position in the buffer + */ + size_t current_position() const { return m_buffer_pos; } - /** - * Reset the buffer position - */ - void buffer_reset() { m_buffer_pos = 0; } - private: - size_t m_main_block_mod, m_final_minimum; - - secure_vector m_buffer; - size_t m_buffer_pos; - }; - -/** -* This class represents keyed filters, i.e. filters that have to be -* fed with a key in order to function. -*/ -class BOTAN_PUBLIC_API(2,0) Keyed_Filter : public Filter - { - public: - /** - * Set the key of this filter - * @param key the key to use - */ - virtual void set_key(const SymmetricKey& key) = 0; - - /** - * Set the initialization vector of this filter. Note: you should - * call set_iv() only after you have called set_key() - * @param iv the initialization vector to use - */ - virtual void set_iv(const InitializationVector& iv) - { - if(iv.length() != 0) - throw Invalid_IV_Length(name(), iv.length()); - } - - /** - * Check whether a key length is valid for this filter - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - bool valid_keylength(size_t length) const - { - return key_spec().valid_keylength(length); - } - - /** - * @return object describing limits on key size - */ - virtual Key_Length_Specification key_spec() const = 0; - - /** - * Check whether an IV length is valid for this filter - * @param length the IV length to be checked for validity - * @return true if the IV length is valid, false otherwise - */ - virtual bool valid_iv_length(size_t length) const - { return (length == 0); } - }; - -/** -* Filter interface for cipher modes -*/ -class BOTAN_PUBLIC_API(2,0) Cipher_Mode_Filter final : public Keyed_Filter, - private Buffered_Filter - { - public: - explicit Cipher_Mode_Filter(Cipher_Mode* t); - - explicit Cipher_Mode_Filter(std::unique_ptr t) : - Cipher_Mode_Filter(t.release()) {} - - void set_iv(const InitializationVector& iv) override; - - void set_key(const SymmetricKey& key) override; - - Key_Length_Specification key_spec() const override; - - bool valid_iv_length(size_t length) const override; - - std::string name() const override; + /** + * Reset the buffer position + */ + void buffer_reset() { m_buffer_pos = 0; } private: - void write(const uint8_t input[], size_t input_length) override; - void start_msg() override; - void end_msg() override; + size_t m_main_block_mod, m_final_minimum; - void buffered_block(const uint8_t input[], size_t input_length) override; - void buffered_final(const uint8_t input[], size_t input_length) override; + secure_vector m_buffer; + size_t m_buffer_pos; +}; - std::unique_ptr m_mode; - std::vector m_nonce; - secure_vector m_buffer; - }; +/** + * This class represents keyed filters, i.e. filters that have to be + * fed with a key in order to function. + */ +class BOTAN_PUBLIC_API(2, 0) Keyed_Filter : public Filter { + public: + /** + * Set the key of this filter + * @param key the key to use + */ + virtual void set_key(const SymmetricKey& key) = 0; + + /** + * Set the initialization vector of this filter. Note: you should + * call set_iv() only after you have called set_key() + * @param iv the initialization vector to use + */ + virtual void set_iv(const InitializationVector& iv) { + if (iv.length() != 0) throw Invalid_IV_Length(name(), iv.length()); + } + + /** + * Check whether a key length is valid for this filter + * @param length the key length to be checked for validity + * @return true if the key length is valid, false otherwise + */ + bool valid_keylength(size_t length) const { return key_spec().valid_keylength(length); } + + /** + * @return object describing limits on key size + */ + virtual Key_Length_Specification key_spec() const = 0; + + /** + * Check whether an IV length is valid for this filter + * @param length the IV length to be checked for validity + * @return true if the IV length is valid, false otherwise + */ + virtual bool valid_iv_length(size_t length) const { return (length == 0); } +}; + +/** + * Filter interface for cipher modes + */ +class BOTAN_PUBLIC_API(2, 0) Cipher_Mode_Filter final : public Keyed_Filter, + private Buffered_Filter { + public: + explicit Cipher_Mode_Filter(Cipher_Mode* t); + + explicit Cipher_Mode_Filter(std::unique_ptr t) : Cipher_Mode_Filter(t.release()) {} + + void set_iv(const InitializationVector& iv) override; + + void set_key(const SymmetricKey& key) override; + + Key_Length_Specification key_spec() const override; + + bool valid_iv_length(size_t length) const override; + + std::string name() const override; + + private: + void write(const uint8_t input[], size_t input_length) override; + void start_msg() override; + void end_msg() override; + + void buffered_block(const uint8_t input[], size_t input_length) override; + void buffered_final(const uint8_t input[], size_t input_length) override; + + std::unique_ptr m_mode; + std::vector m_nonce; + secure_vector m_buffer; +}; // deprecated aliases, will be removed in a future major release typedef Cipher_Mode_Filter Transform_Filter; typedef Transform_Filter Transformation_Filter; /* -* Get a cipher object -*/ + * Get a cipher object + */ /** -* Factory method for general symmetric cipher filters. No key will be -* set in the filter. -* -* @param algo_spec the name of the desired cipher -* @param direction determines whether the filter will be an encrypting or -* decrypting filter -* @return pointer to the encryption or decryption filter -*/ -inline Keyed_Filter* get_cipher(const std::string& algo_spec, - Cipher_Dir direction) - { - std::unique_ptr c(Cipher_Mode::create_or_throw(algo_spec, direction)); - return new Cipher_Mode_Filter(c.release()); - } + * Factory method for general symmetric cipher filters. No key will be + * set in the filter. + * + * @param algo_spec the name of the desired cipher + * @param direction determines whether the filter will be an encrypting or + * decrypting filter + * @return pointer to the encryption or decryption filter + */ +inline Keyed_Filter* get_cipher(const std::string& algo_spec, Cipher_Dir direction) { + std::unique_ptr c(Cipher_Mode::create_or_throw(algo_spec, direction)); + return new Cipher_Mode_Filter(c.release()); +} /** -* Factory method for general symmetric cipher filters. -* @param algo_spec the name of the desired cipher -* @param key the key to be used for encryption/decryption performed by -* the filter -* @param direction determines whether the filter will be an encrypting -* or decrypting filter -* @return pointer to the encryption or decryption filter -*/ -inline Keyed_Filter* get_cipher(const std::string& algo_spec, - const SymmetricKey& key, - Cipher_Dir direction) - { - Keyed_Filter* cipher = get_cipher(algo_spec, direction); - cipher->set_key(key); - return cipher; - } + * Factory method for general symmetric cipher filters. + * @param algo_spec the name of the desired cipher + * @param key the key to be used for encryption/decryption performed by + * the filter + * @param direction determines whether the filter will be an encrypting + * or decrypting filter + * @return pointer to the encryption or decryption filter + */ +inline Keyed_Filter* get_cipher(const std::string& algo_spec, const SymmetricKey& key, + Cipher_Dir direction) { + Keyed_Filter* cipher = get_cipher(algo_spec, direction); + cipher->set_key(key); + return cipher; +} /** -* Factory method for general symmetric cipher filters. -* @param algo_spec the name of the desired cipher -* @param key the key to be used for encryption/decryption performed by -* the filter -* @param iv the initialization vector to be used -* @param direction determines whether the filter will be an encrypting -* or decrypting filter -* @return pointer to newly allocated encryption or decryption filter -*/ -inline Keyed_Filter* get_cipher(const std::string& algo_spec, - const SymmetricKey& key, - const InitializationVector& iv, - Cipher_Dir direction) - { - Keyed_Filter* cipher = get_cipher(algo_spec, key, direction); - if(iv.length()) - cipher->set_iv(iv); - return cipher; - } + * Factory method for general symmetric cipher filters. + * @param algo_spec the name of the desired cipher + * @param key the key to be used for encryption/decryption performed by + * the filter + * @param iv the initialization vector to be used + * @param direction determines whether the filter will be an encrypting + * or decrypting filter + * @return pointer to newly allocated encryption or decryption filter + */ +inline Keyed_Filter* get_cipher(const std::string& algo_spec, const SymmetricKey& key, + const InitializationVector& iv, Cipher_Dir direction) { + Keyed_Filter* cipher = get_cipher(algo_spec, key, direction); + if (iv.length()) cipher->set_iv(iv); + return cipher; +} #if defined(BOTAN_HAS_STREAM_CIPHER) /** -* Stream Cipher Filter -*/ -class BOTAN_PUBLIC_API(2,0) StreamCipher_Filter final : public Keyed_Filter - { + * Stream Cipher Filter + */ +class BOTAN_PUBLIC_API(2, 0) StreamCipher_Filter final : public Keyed_Filter { public: + std::string name() const override { return m_cipher->name(); } - std::string name() const override { return m_cipher->name(); } + /** + * Write input data + * @param input data + * @param input_len length of input in bytes + */ + void write(const uint8_t input[], size_t input_len) override; - /** - * Write input data - * @param input data - * @param input_len length of input in bytes - */ - void write(const uint8_t input[], size_t input_len) override; + bool valid_iv_length(size_t iv_len) const override { return m_cipher->valid_iv_length(iv_len); } - bool valid_iv_length(size_t iv_len) const override - { return m_cipher->valid_iv_length(iv_len); } + /** + * Set the initialization vector for this filter. + * @param iv the initialization vector to set + */ + void set_iv(const InitializationVector& iv) override { + m_cipher->set_iv(iv.begin(), iv.length()); + } - /** - * Set the initialization vector for this filter. - * @param iv the initialization vector to set - */ - void set_iv(const InitializationVector& iv) override - { - m_cipher->set_iv(iv.begin(), iv.length()); - } + /** + * Set the key of this filter. + * @param key the key to set + */ + void set_key(const SymmetricKey& key) override { m_cipher->set_key(key); } - /** - * Set the key of this filter. - * @param key the key to set - */ - void set_key(const SymmetricKey& key) override { m_cipher->set_key(key); } + Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } - Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } + /** + * Construct a stream cipher filter. + * @param cipher a cipher object to use + */ + explicit StreamCipher_Filter(StreamCipher* cipher); - /** - * Construct a stream cipher filter. - * @param cipher a cipher object to use - */ - explicit StreamCipher_Filter(StreamCipher* cipher); + /** + * Construct a stream cipher filter. + * @param cipher a cipher object to use + * @param key the key to use inside this filter + */ + StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key); - /** - * Construct a stream cipher filter. - * @param cipher a cipher object to use - * @param key the key to use inside this filter - */ - StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key); + /** + * Construct a stream cipher filter. + * @param cipher the name of the desired cipher + */ + explicit StreamCipher_Filter(const std::string& cipher); - /** - * Construct a stream cipher filter. - * @param cipher the name of the desired cipher - */ - explicit StreamCipher_Filter(const std::string& cipher); + /** + * Construct a stream cipher filter. + * @param cipher the name of the desired cipher + * @param key the key to use inside this filter + */ + StreamCipher_Filter(const std::string& cipher, const SymmetricKey& key); - /** - * Construct a stream cipher filter. - * @param cipher the name of the desired cipher - * @param key the key to use inside this filter - */ - StreamCipher_Filter(const std::string& cipher, const SymmetricKey& key); private: - secure_vector m_buffer; - std::unique_ptr m_cipher; - }; + secure_vector m_buffer; + std::unique_ptr m_cipher; +}; #endif #if defined(BOTAN_HAS_HASH) /** -* Hash Filter. -*/ -class BOTAN_PUBLIC_API(2,0) Hash_Filter final : public Filter - { + * Hash Filter. + */ +class BOTAN_PUBLIC_API(2, 0) Hash_Filter final : public Filter { public: - void write(const uint8_t input[], size_t len) override { m_hash->update(input, len); } - void end_msg() override; + void write(const uint8_t input[], size_t len) override { m_hash->update(input, len); } + void end_msg() override; - std::string name() const override { return m_hash->name(); } + std::string name() const override { return m_hash->name(); } - /** - * Construct a hash filter. - * @param hash the hash function to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the hashfunction - * hash. Otherwise, specify a smaller value here so that the - * output of the hash algorithm will be cut off. - */ - Hash_Filter(HashFunction* hash, size_t len = 0) : - m_hash(hash), m_out_len(len) {} + /** + * Construct a hash filter. + * @param hash the hash function to use + * @param len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the hashfunction + * hash. Otherwise, specify a smaller value here so that the + * output of the hash algorithm will be cut off. + */ + Hash_Filter(HashFunction* hash, size_t len = 0) : m_hash(hash), m_out_len(len) {} - /** - * Construct a hash filter. - * @param request the name of the hash algorithm to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the hashfunction - * hash. Otherwise, specify a smaller value here so that the - * output of the hash algorithm will be cut off. - */ - Hash_Filter(const std::string& request, size_t len = 0); + /** + * Construct a hash filter. + * @param request the name of the hash algorithm to use + * @param len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the hashfunction + * hash. Otherwise, specify a smaller value here so that the + * output of the hash algorithm will be cut off. + */ + Hash_Filter(const std::string& request, size_t len = 0); private: - std::unique_ptr m_hash; - const size_t m_out_len; - }; + std::unique_ptr m_hash; + const size_t m_out_len; +}; #endif #if defined(BOTAN_HAS_MAC) /** -* MessageAuthenticationCode Filter. -*/ -class BOTAN_PUBLIC_API(2,0) MAC_Filter final : public Keyed_Filter - { + * MessageAuthenticationCode Filter. + */ +class BOTAN_PUBLIC_API(2, 0) MAC_Filter final : public Keyed_Filter { public: - void write(const uint8_t input[], size_t len) override { m_mac->update(input, len); } - void end_msg() override; + void write(const uint8_t input[], size_t len) override { m_mac->update(input, len); } + void end_msg() override; - std::string name() const override { return m_mac->name(); } + std::string name() const override { return m_mac->name(); } - /** - * Set the key of this filter. - * @param key the key to set - */ - void set_key(const SymmetricKey& key) override { m_mac->set_key(key); } + /** + * Set the key of this filter. + * @param key the key to set + */ + void set_key(const SymmetricKey& key) override { m_mac->set_key(key); } - Key_Length_Specification key_spec() const override { return m_mac->key_spec(); } + Key_Length_Specification key_spec() const override { return m_mac->key_spec(); } - /** - * Construct a MAC filter. The MAC key will be left empty. - * @param mac the MAC to use - * @param out_len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(MessageAuthenticationCode* mac, - size_t out_len = 0) : - m_mac(mac), - m_out_len(out_len) - { - } + /** + * Construct a MAC filter. The MAC key will be left empty. + * @param mac the MAC to use + * @param out_len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the + * MAC. Otherwise, specify a smaller value here so that the + * output of the MAC will be cut off. + */ + MAC_Filter(MessageAuthenticationCode* mac, size_t out_len = 0) + : m_mac(mac), m_out_len(out_len) {} - /** - * Construct a MAC filter. - * @param mac the MAC to use - * @param key the MAC key to use - * @param out_len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(MessageAuthenticationCode* mac, - const SymmetricKey& key, - size_t out_len = 0) : - m_mac(mac), - m_out_len(out_len) - { - m_mac->set_key(key); - } + /** + * Construct a MAC filter. + * @param mac the MAC to use + * @param key the MAC key to use + * @param out_len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the + * MAC. Otherwise, specify a smaller value here so that the + * output of the MAC will be cut off. + */ + MAC_Filter(MessageAuthenticationCode* mac, const SymmetricKey& key, size_t out_len = 0) + : m_mac(mac), m_out_len(out_len) { + m_mac->set_key(key); + } - /** - * Construct a MAC filter. The MAC key will be left empty. - * @param mac the name of the MAC to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(const std::string& mac, size_t len = 0); + /** + * Construct a MAC filter. The MAC key will be left empty. + * @param mac the name of the MAC to use + * @param len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the + * MAC. Otherwise, specify a smaller value here so that the + * output of the MAC will be cut off. + */ + MAC_Filter(const std::string& mac, size_t len = 0); + + /** + * Construct a MAC filter. + * @param mac the name of the MAC to use + * @param key the MAC key to use + * @param len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the + * MAC. Otherwise, specify a smaller value here so that the + * output of the MAC will be cut off. + */ + MAC_Filter(const std::string& mac, const SymmetricKey& key, size_t len = 0); - /** - * Construct a MAC filter. - * @param mac the name of the MAC to use - * @param key the MAC key to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(const std::string& mac, const SymmetricKey& key, - size_t len = 0); private: - std::unique_ptr m_mac; - const size_t m_out_len; - }; + std::unique_ptr m_mac; + const size_t m_out_len; +}; #endif #if defined(BOTAN_HAS_COMPRESSION) @@ -8673,352 +7970,336 @@ class Compression_Algorithm; class Decompression_Algorithm; /** -* Filter interface for compression -*/ -class BOTAN_PUBLIC_API(2,0) Compression_Filter final : public Filter - { + * Filter interface for compression + */ +class BOTAN_PUBLIC_API(2, 0) Compression_Filter final : public Filter { public: - void start_msg() override; - void write(const uint8_t input[], size_t input_length) override; - void end_msg() override; + void start_msg() override; + void write(const uint8_t input[], size_t input_length) override; + void end_msg() override; - void flush(); + void flush(); - std::string name() const override; + std::string name() const override; - Compression_Filter(const std::string& type, - size_t compression_level, - size_t buffer_size = 4096); + Compression_Filter(const std::string& type, size_t compression_level, + size_t buffer_size = 4096); + + ~Compression_Filter(); - ~Compression_Filter(); private: - std::unique_ptr m_comp; - size_t m_buffersize, m_level; - secure_vector m_buffer; - }; + std::unique_ptr m_comp; + size_t m_buffersize, m_level; + secure_vector m_buffer; +}; /** -* Filter interface for decompression -*/ -class BOTAN_PUBLIC_API(2,0) Decompression_Filter final : public Filter - { + * Filter interface for decompression + */ +class BOTAN_PUBLIC_API(2, 0) Decompression_Filter final : public Filter { public: - void start_msg() override; - void write(const uint8_t input[], size_t input_length) override; - void end_msg() override; + void start_msg() override; + void write(const uint8_t input[], size_t input_length) override; + void end_msg() override; - std::string name() const override; + std::string name() const override; - Decompression_Filter(const std::string& type, - size_t buffer_size = 4096); + Decompression_Filter(const std::string& type, size_t buffer_size = 4096); + + ~Decompression_Filter(); - ~Decompression_Filter(); private: - std::unique_ptr m_comp; - std::size_t m_buffersize; - secure_vector m_buffer; - }; + std::unique_ptr m_comp; + std::size_t m_buffersize; + secure_vector m_buffer; +}; #endif /** -* This class represents a Base64 encoder. -*/ -class BOTAN_PUBLIC_API(2,0) Base64_Encoder final : public Filter - { + * This class represents a Base64 encoder. + */ +class BOTAN_PUBLIC_API(2, 0) Base64_Encoder final : public Filter { public: - std::string name() const override { return "Base64_Encoder"; } + std::string name() const override { return "Base64_Encoder"; } - /** - * Input a part of a message to the encoder. - * @param input the message to input as a byte array - * @param length the length of the byte array input - */ - void write(const uint8_t input[], size_t length) override; + /** + * Input a part of a message to the encoder. + * @param input the message to input as a byte array + * @param length the length of the byte array input + */ + void write(const uint8_t input[], size_t length) override; - /** - * Inform the Encoder that the current message shall be closed. - */ - void end_msg() override; + /** + * Inform the Encoder that the current message shall be closed. + */ + void end_msg() override; + + /** + * Create a base64 encoder. + * @param breaks whether to use line breaks in the output + * @param length the length of the lines of the output + * @param t_n whether to use a trailing newline + */ + Base64_Encoder(bool breaks = false, size_t length = 72, bool t_n = false); - /** - * Create a base64 encoder. - * @param breaks whether to use line breaks in the output - * @param length the length of the lines of the output - * @param t_n whether to use a trailing newline - */ - Base64_Encoder(bool breaks = false, size_t length = 72, - bool t_n = false); private: - void encode_and_send(const uint8_t input[], size_t length, - bool final_inputs = false); - void do_output(const uint8_t output[], size_t length); + void encode_and_send(const uint8_t input[], size_t length, bool final_inputs = false); + void do_output(const uint8_t output[], size_t length); - const size_t m_line_length; - const bool m_trailing_newline; - std::vector m_in, m_out; - size_t m_position, m_out_position; - }; + const size_t m_line_length; + const bool m_trailing_newline; + std::vector m_in, m_out; + size_t m_position, m_out_position; +}; /** -* This object represents a Base64 decoder. -*/ -class BOTAN_PUBLIC_API(2,0) Base64_Decoder final : public Filter - { + * This object represents a Base64 decoder. + */ +class BOTAN_PUBLIC_API(2, 0) Base64_Decoder final : public Filter { public: - std::string name() const override { return "Base64_Decoder"; } + std::string name() const override { return "Base64_Decoder"; } - /** - * Input a part of a message to the decoder. - * @param input the message to input as a byte array - * @param length the length of the byte array input - */ - void write(const uint8_t input[], size_t length) override; + /** + * Input a part of a message to the decoder. + * @param input the message to input as a byte array + * @param length the length of the byte array input + */ + void write(const uint8_t input[], size_t length) override; - /** - * Finish up the current message - */ - void end_msg() override; + /** + * Finish up the current message + */ + void end_msg() override; + + /** + * Create a base64 decoder. + * @param checking the type of checking that shall be performed by + * the decoder + */ + explicit Base64_Decoder(Decoder_Checking checking = NONE); - /** - * Create a base64 decoder. - * @param checking the type of checking that shall be performed by - * the decoder - */ - explicit Base64_Decoder(Decoder_Checking checking = NONE); private: - const Decoder_Checking m_checking; - std::vector m_in, m_out; - size_t m_position; - }; + const Decoder_Checking m_checking; + std::vector m_in, m_out; + size_t m_position; +}; /** -* Converts arbitrary binary data to hex strings, optionally with -* newlines inserted -*/ -class BOTAN_PUBLIC_API(2,0) Hex_Encoder final : public Filter - { + * Converts arbitrary binary data to hex strings, optionally with + * newlines inserted + */ +class BOTAN_PUBLIC_API(2, 0) Hex_Encoder final : public Filter { public: - /** - * Whether to use uppercase or lowercase letters for the encoded string. - */ - enum Case { Uppercase, Lowercase }; + /** + * Whether to use uppercase or lowercase letters for the encoded string. + */ + enum Case { Uppercase, Lowercase }; - std::string name() const override { return "Hex_Encoder"; } + std::string name() const override { return "Hex_Encoder"; } - void write(const uint8_t in[], size_t length) override; - void end_msg() override; + void write(const uint8_t in[], size_t length) override; + void end_msg() override; - /** - * Create a hex encoder. - * @param the_case the case to use in the encoded strings. - */ - explicit Hex_Encoder(Case the_case); + /** + * Create a hex encoder. + * @param the_case the case to use in the encoded strings. + */ + explicit Hex_Encoder(Case the_case); + + /** + * Create a hex encoder. + * @param newlines should newlines be used + * @param line_length if newlines are used, how long are lines + * @param the_case the case to use in the encoded strings + */ + Hex_Encoder(bool newlines = false, size_t line_length = 72, Case the_case = Uppercase); - /** - * Create a hex encoder. - * @param newlines should newlines be used - * @param line_length if newlines are used, how long are lines - * @param the_case the case to use in the encoded strings - */ - Hex_Encoder(bool newlines = false, - size_t line_length = 72, - Case the_case = Uppercase); private: - void encode_and_send(const uint8_t[], size_t); + void encode_and_send(const uint8_t[], size_t); - const Case m_casing; - const size_t m_line_length; - std::vector m_in, m_out; - size_t m_position, m_counter; - }; + const Case m_casing; + const size_t m_line_length; + std::vector m_in, m_out; + size_t m_position, m_counter; +}; /** -* Converts hex strings to bytes -*/ -class BOTAN_PUBLIC_API(2,0) Hex_Decoder final : public Filter - { + * Converts hex strings to bytes + */ +class BOTAN_PUBLIC_API(2, 0) Hex_Decoder final : public Filter { public: - std::string name() const override { return "Hex_Decoder"; } + std::string name() const override { return "Hex_Decoder"; } - void write(const uint8_t[], size_t) override; - void end_msg() override; + void write(const uint8_t[], size_t) override; + void end_msg() override; + + /** + * Construct a Hex Decoder using the specified + * character checking. + * @param checking the checking to use during decoding. + */ + explicit Hex_Decoder(Decoder_Checking checking = NONE); - /** - * Construct a Hex Decoder using the specified - * character checking. - * @param checking the checking to use during decoding. - */ - explicit Hex_Decoder(Decoder_Checking checking = NONE); private: - const Decoder_Checking m_checking; - std::vector m_in, m_out; - size_t m_position; - }; + const Decoder_Checking m_checking; + std::vector m_in, m_out; + size_t m_position; +}; /** -* BitBucket is a filter which simply discards all inputs -*/ -class BOTAN_PUBLIC_API(2,0) BitBucket final : public Filter - { + * BitBucket is a filter which simply discards all inputs + */ +class BOTAN_PUBLIC_API(2, 0) BitBucket final : public Filter { public: - void write(const uint8_t[], size_t) override { /* discard */ } + void write(const uint8_t[], size_t) override { /* discard */ } - std::string name() const override { return "BitBucket"; } - }; + std::string name() const override { return "BitBucket"; } +}; /** -* This class represents Filter chains. A Filter chain is an ordered -* concatenation of Filters, the input to a Chain sequentially passes -* through all the Filters contained in the Chain. -*/ + * This class represents Filter chains. A Filter chain is an ordered + * concatenation of Filters, the input to a Chain sequentially passes + * through all the Filters contained in the Chain. + */ -class BOTAN_PUBLIC_API(2,0) Chain final : public Fanout_Filter - { +class BOTAN_PUBLIC_API(2, 0) Chain final : public Fanout_Filter { public: - void write(const uint8_t input[], size_t length) override { send(input, length); } + void write(const uint8_t input[], size_t length) override { send(input, length); } - std::string name() const override { return "Chain"; } + std::string name() const override { return "Chain"; } - /** - * Construct a chain of up to four filters. The filters are set - * up in the same order as the arguments. - */ - Chain(Filter* = nullptr, Filter* = nullptr, - Filter* = nullptr, Filter* = nullptr); + /** + * Construct a chain of up to four filters. The filters are set + * up in the same order as the arguments. + */ + Chain(Filter* = nullptr, Filter* = nullptr, Filter* = nullptr, Filter* = nullptr); - /** - * Construct a chain from range of filters - * @param filter_arr the list of filters - * @param length how many filters - */ - Chain(Filter* filter_arr[], size_t length); - }; + /** + * Construct a chain from range of filters + * @param filter_arr the list of filters + * @param length how many filters + */ + Chain(Filter* filter_arr[], size_t length); +}; /** -* This class represents a fork filter, whose purpose is to fork the -* flow of data. It causes an input message to result in n messages at -* the end of the filter, where n is the number of forks. -*/ -class BOTAN_PUBLIC_API(2,0) Fork : public Fanout_Filter - { + * This class represents a fork filter, whose purpose is to fork the + * flow of data. It causes an input message to result in n messages at + * the end of the filter, where n is the number of forks. + */ +class BOTAN_PUBLIC_API(2, 0) Fork : public Fanout_Filter { public: - void write(const uint8_t input[], size_t length) override { send(input, length); } - void set_port(size_t n) { Fanout_Filter::set_port(n); } + void write(const uint8_t input[], size_t length) override { send(input, length); } + void set_port(size_t n) { Fanout_Filter::set_port(n); } - std::string name() const override { return "Fork"; } + std::string name() const override { return "Fork"; } - /** - * Construct a Fork filter with up to four forks. - */ - Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr); + /** + * Construct a Fork filter with up to four forks. + */ + Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr); - /** - * Construct a Fork from range of filters - * @param filter_arr the list of filters - * @param length how many filters - */ - Fork(Filter* filter_arr[], size_t length); - }; + /** + * Construct a Fork from range of filters + * @param filter_arr the list of filters + * @param length how many filters + */ + Fork(Filter* filter_arr[], size_t length); +}; #if defined(BOTAN_HAS_THREAD_UTILS) /** -* This class is a threaded version of the Fork filter. While this uses -* threads, the class itself is NOT thread-safe. This is meant as a drop- -* in replacement for Fork where performance gains are possible. -*/ -class BOTAN_PUBLIC_API(2,0) Threaded_Fork final : public Fork - { + * This class is a threaded version of the Fork filter. While this uses + * threads, the class itself is NOT thread-safe. This is meant as a drop- + * in replacement for Fork where performance gains are possible. + */ +class BOTAN_PUBLIC_API(2, 0) Threaded_Fork final : public Fork { public: - std::string name() const override; + std::string name() const override; - /** - * Construct a Threaded_Fork filter with up to four forks. - */ - Threaded_Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr); + /** + * Construct a Threaded_Fork filter with up to four forks. + */ + Threaded_Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr); - /** - * Construct a Threaded_Fork from range of filters - * @param filter_arr the list of filters - * @param length how many filters - */ - Threaded_Fork(Filter* filter_arr[], size_t length); + /** + * Construct a Threaded_Fork from range of filters + * @param filter_arr the list of filters + * @param length how many filters + */ + Threaded_Fork(Filter* filter_arr[], size_t length); - ~Threaded_Fork(); + ~Threaded_Fork(); private: - void set_next(Filter* f[], size_t n); - void send(const uint8_t in[], size_t length) override; - void thread_delegate_work(const uint8_t input[], size_t length); - void thread_entry(Filter* filter); + void set_next(Filter* f[], size_t n); + void send(const uint8_t in[], size_t length) override; + void thread_delegate_work(const uint8_t input[], size_t length); + void thread_entry(Filter* filter); - std::vector> m_threads; - std::unique_ptr m_thread_data; - }; + std::vector> m_threads; + std::unique_ptr m_thread_data; +}; #endif -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(hash_id) +// BOTAN_FUTURE_INTERNAL_HEADER(hash_id) namespace Botan { /** -* Return the PKCS #1 hash identifier -* @see RFC 3447 section 9.2 -* @param hash_name the name of the hash function -* @return uint8_t sequence identifying the hash -* @throw Invalid_Argument if the hash has no known PKCS #1 hash id -*/ -BOTAN_PUBLIC_API(2,0) std::vector pkcs_hash_id(const std::string& hash_name); + * Return the PKCS #1 hash identifier + * @see RFC 3447 section 9.2 + * @param hash_name the name of the hash function + * @return uint8_t sequence identifying the hash + * @throw Invalid_Argument if the hash has no known PKCS #1 hash id + */ +BOTAN_PUBLIC_API(2, 0) std::vector pkcs_hash_id(const std::string& hash_name); /** -* Return the IEEE 1363 hash identifier -* @param hash_name the name of the hash function -* @return uint8_t code identifying the hash, or 0 if not known -*/ -BOTAN_PUBLIC_API(2,0) uint8_t ieee1363_hash_id(const std::string& hash_name); + * Return the IEEE 1363 hash identifier + * @param hash_name the name of the hash function + * @return uint8_t code identifying the hash, or 0 if not known + */ +BOTAN_PUBLIC_API(2, 0) uint8_t ieee1363_hash_id(const std::string& hash_name); -} +} // namespace Botan namespace Botan { /** -* Perform hex encoding -* @param output an array of at least input_length*2 bytes -* @param input is some binary data -* @param input_length length of input in bytes -* @param uppercase should output be upper or lower case? -*/ -void BOTAN_PUBLIC_API(2,0) hex_encode(char output[], - const uint8_t input[], - size_t input_length, - bool uppercase = true); + * Perform hex encoding + * @param output an array of at least input_length*2 bytes + * @param input is some binary data + * @param input_length length of input in bytes + * @param uppercase should output be upper or lower case? + */ +void BOTAN_PUBLIC_API(2, 0) + hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase = true); /** -* Perform hex encoding -* @param input some input -* @param input_length length of input in bytes -* @param uppercase should output be upper or lower case? -* @return hexadecimal representation of input -*/ -std::string BOTAN_PUBLIC_API(2,0) hex_encode(const uint8_t input[], - size_t input_length, - bool uppercase = true); + * Perform hex encoding + * @param input some input + * @param input_length length of input in bytes + * @param uppercase should output be upper or lower case? + * @return hexadecimal representation of input + */ +std::string BOTAN_PUBLIC_API(2, 0) + hex_encode(const uint8_t input[], size_t input_length, bool uppercase = true); /** -* Perform hex encoding -* @param input some input -* @param uppercase should output be upper or lower case? -* @return hexadecimal representation of input -*/ -template -std::string hex_encode(const std::vector& input, - bool uppercase = true) - { - return hex_encode(input.data(), input.size(), uppercase); - } + * Perform hex encoding + * @param input some input + * @param uppercase should output be upper or lower case? + * @return hexadecimal representation of input + */ +template +std::string hex_encode(const std::vector& input, bool uppercase = true) { + return hex_encode(input.data(), input.size(), uppercase); +} /** * Perform hex decoding @@ -9033,11 +8314,8 @@ std::string hex_encode(const std::vector& input, exception if whitespace is encountered * @return number of bytes written to output */ -size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool ignore_ws = true); +size_t BOTAN_PUBLIC_API(2, 0) hex_decode(uint8_t output[], const char input[], size_t input_length, + size_t& input_consumed, bool ignore_ws = true); /** * Perform hex decoding @@ -9048,10 +8326,8 @@ size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], exception if whitespace is encountered * @return number of bytes written to output */ -size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], - const char input[], - size_t input_length, - bool ignore_ws = true); +size_t BOTAN_PUBLIC_API(2, 0) + hex_decode(uint8_t output[], const char input[], size_t input_length, bool ignore_ws = true); /** * Perform hex decoding @@ -9061,9 +8337,8 @@ size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], exception if whitespace is encountered * @return number of bytes written to output */ -size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], - const std::string& input, - bool ignore_ws = true); +size_t BOTAN_PUBLIC_API(2, 0) + hex_decode(uint8_t output[], const std::string& input, bool ignore_ws = true); /** * Perform hex decoding @@ -9073,10 +8348,8 @@ size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], exception if whitespace is encountered * @return decoded hex output */ -std::vector BOTAN_PUBLIC_API(2,0) -hex_decode(const char input[], - size_t input_length, - bool ignore_ws = true); +std::vector BOTAN_PUBLIC_API(2, 0) + hex_decode(const char input[], size_t input_length, bool ignore_ws = true); /** * Perform hex decoding @@ -9085,10 +8358,8 @@ hex_decode(const char input[], exception if whitespace is encountered * @return decoded hex output */ -std::vector BOTAN_PUBLIC_API(2,0) -hex_decode(const std::string& input, - bool ignore_ws = true); - +std::vector BOTAN_PUBLIC_API(2, 0) + hex_decode(const std::string& input, bool ignore_ws = true); /** * Perform hex decoding @@ -9098,10 +8369,8 @@ hex_decode(const std::string& input, exception if whitespace is encountered * @return decoded hex output */ -secure_vector BOTAN_PUBLIC_API(2,0) -hex_decode_locked(const char input[], - size_t input_length, - bool ignore_ws = true); +secure_vector BOTAN_PUBLIC_API(2, 0) + hex_decode_locked(const char input[], size_t input_length, bool ignore_ws = true); /** * Perform hex decoding @@ -9110,1290 +8379,1176 @@ hex_decode_locked(const char input[], exception if whitespace is encountered * @return decoded hex output */ -secure_vector BOTAN_PUBLIC_API(2,0) -hex_decode_locked(const std::string& input, - bool ignore_ws = true); +secure_vector BOTAN_PUBLIC_API(2, 0) + hex_decode_locked(const std::string& input, bool ignore_ws = true); -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(hmac.h) +// BOTAN_FUTURE_INTERNAL_HEADER(hmac.h) namespace Botan { /** -* HMAC -*/ -class BOTAN_PUBLIC_API(2,0) HMAC final : public MessageAuthenticationCode - { + * HMAC + */ +class BOTAN_PUBLIC_API(2, 0) HMAC final : public MessageAuthenticationCode { public: - void clear() override; - std::string name() const override; - MessageAuthenticationCode* clone() const override; + void clear() override; + std::string name() const override; + MessageAuthenticationCode* clone() const override; - size_t output_length() const override; + size_t output_length() const override; - Key_Length_Specification key_spec() const override; + Key_Length_Specification key_spec() const override; - /** - * @param hash the hash to use for HMACing - */ - explicit HMAC(HashFunction* hash); + /** + * @param hash the hash to use for HMACing + */ + explicit HMAC(HashFunction* hash); + + HMAC(const HMAC&) = delete; + HMAC& operator=(const HMAC&) = delete; - HMAC(const HMAC&) = delete; - HMAC& operator=(const HMAC&) = delete; private: - void add_data(const uint8_t[], size_t) override; - void final_result(uint8_t[]) override; - void key_schedule(const uint8_t[], size_t) override; + void add_data(const uint8_t[], size_t) override; + void final_result(uint8_t[]) override; + void key_schedule(const uint8_t[], size_t) override; - std::unique_ptr m_hash; - secure_vector m_ikey, m_okey; - size_t m_hash_output_length; - size_t m_hash_block_size; - }; + std::unique_ptr m_hash; + secure_vector m_ikey, m_okey; + size_t m_hash_output_length; + size_t m_hash_block_size; +}; -} +} // namespace Botan namespace Botan { /** -* Inherited by RNGs which maintain in-process state, like HMAC_DRBG. -* On Unix these RNGs are vulnerable to problems with fork, where the -* RNG state is duplicated, and the parent and child process RNGs will -* produce identical output until one of them reseeds. Stateful_RNG -* reseeds itself whenever a fork is detected, or after a set number of -* bytes have been output. -* -* Not implemented by RNGs which access an external RNG, such as the -* system PRNG or a hardware RNG. -*/ -class BOTAN_PUBLIC_API(2,0) Stateful_RNG : public RandomNumberGenerator - { + * Inherited by RNGs which maintain in-process state, like HMAC_DRBG. + * On Unix these RNGs are vulnerable to problems with fork, where the + * RNG state is duplicated, and the parent and child process RNGs will + * produce identical output until one of them reseeds. Stateful_RNG + * reseeds itself whenever a fork is detected, or after a set number of + * bytes have been output. + * + * Not implemented by RNGs which access an external RNG, such as the + * system PRNG or a hardware RNG. + */ +class BOTAN_PUBLIC_API(2, 0) Stateful_RNG : public RandomNumberGenerator { public: - /** - * @param rng is a reference to some RNG which will be used - * to perform the periodic reseeding - * @param entropy_sources will be polled to perform reseeding periodically - * @param reseed_interval specifies a limit of how many times - * the RNG will be called before automatic reseeding is performed - */ - Stateful_RNG(RandomNumberGenerator& rng, - Entropy_Sources& entropy_sources, - size_t reseed_interval) : - m_underlying_rng(&rng), - m_entropy_sources(&entropy_sources), - m_reseed_interval(reseed_interval) - {} + /** + * @param rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + Stateful_RNG(RandomNumberGenerator& rng, Entropy_Sources& entropy_sources, + size_t reseed_interval) + : m_underlying_rng(&rng), + m_entropy_sources(&entropy_sources), + m_reseed_interval(reseed_interval) {} - /** - * @param rng is a reference to some RNG which will be used - * to perform the periodic reseeding - * @param reseed_interval specifies a limit of how many times - * the RNG will be called before automatic reseeding is performed - */ - Stateful_RNG(RandomNumberGenerator& rng, size_t reseed_interval) : - m_underlying_rng(&rng), - m_reseed_interval(reseed_interval) - {} + /** + * @param rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + Stateful_RNG(RandomNumberGenerator& rng, size_t reseed_interval) + : m_underlying_rng(&rng), m_reseed_interval(reseed_interval) {} - /** - * @param entropy_sources will be polled to perform reseeding periodically - * @param reseed_interval specifies a limit of how many times - * the RNG will be called before automatic reseeding is performed - */ - Stateful_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval) : - m_entropy_sources(&entropy_sources), - m_reseed_interval(reseed_interval) - {} + /** + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + Stateful_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval) + : m_entropy_sources(&entropy_sources), m_reseed_interval(reseed_interval) {} - /** - * In this case, automatic reseeding is impossible - */ - Stateful_RNG() : m_reseed_interval(0) {} + /** + * In this case, automatic reseeding is impossible + */ + Stateful_RNG() : m_reseed_interval(0) {} - /** - * Consume this input and mark the RNG as initialized regardless - * of the length of the input or the current seeded state of - * the RNG. - */ - void initialize_with(const uint8_t input[], size_t length); + /** + * Consume this input and mark the RNG as initialized regardless + * of the length of the input or the current seeded state of + * the RNG. + */ + void initialize_with(const uint8_t input[], size_t length); - bool is_seeded() const override final; + bool is_seeded() const override final; - bool accepts_input() const override final { return true; } + bool accepts_input() const override final { return true; } - /** - * Mark state as requiring a reseed on next use - */ - void force_reseed(); + /** + * Mark state as requiring a reseed on next use + */ + void force_reseed(); - void reseed_from_rng(RandomNumberGenerator& rng, - size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS) override final; + void reseed_from_rng(RandomNumberGenerator& rng, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS) override final; - /** - * Overrides default implementation and also includes the current - * process ID and the reseed counter. - */ - void randomize_with_ts_input(uint8_t output[], size_t output_len) override final; + /** + * Overrides default implementation and also includes the current + * process ID and the reseed counter. + */ + void randomize_with_ts_input(uint8_t output[], size_t output_len) override final; - /** - * Poll provided sources for up to poll_bits bits of entropy - * or until the timeout expires. Returns estimate of the number - * of bits collected. - */ - size_t reseed(Entropy_Sources& srcs, - size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, - std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override; + /** + * Poll provided sources for up to poll_bits bits of entropy + * or until the timeout expires. Returns estimate of the number + * of bits collected. + */ + size_t reseed( + Entropy_Sources& srcs, size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override; - /** - * @return intended security level of this DRBG - */ - virtual size_t security_level() const = 0; + /** + * @return intended security level of this DRBG + */ + virtual size_t security_level() const = 0; - /** - * Some DRBGs have a notion of the maximum number of bytes per - * request. Longer requests (to randomize) will be treated as - * multiple requests, and may initiate reseeding multiple times, - * depending on the values of max_number_of_bytes_per_request and - * reseed_interval(). This function returns zero if the RNG in - * question does not have such a notion. - * - * @return max number of bytes per request (or zero) - */ - virtual size_t max_number_of_bytes_per_request() const = 0; + /** + * Some DRBGs have a notion of the maximum number of bytes per + * request. Longer requests (to randomize) will be treated as + * multiple requests, and may initiate reseeding multiple times, + * depending on the values of max_number_of_bytes_per_request and + * reseed_interval(). This function returns zero if the RNG in + * question does not have such a notion. + * + * @return max number of bytes per request (or zero) + */ + virtual size_t max_number_of_bytes_per_request() const = 0; - size_t reseed_interval() const { return m_reseed_interval; } + size_t reseed_interval() const { return m_reseed_interval; } - void clear() override; + void clear() override; protected: - void reseed_check(); + void reseed_check(); - /** - * Called by a subclass to notify that a reseed has been - * successfully performed. - */ - void reset_reseed_counter() { m_reseed_counter = 1; } + /** + * Called by a subclass to notify that a reseed has been + * successfully performed. + */ + void reset_reseed_counter() { m_reseed_counter = 1; } private: - // A non-owned and possibly null pointer to shared RNG - RandomNumberGenerator* m_underlying_rng = nullptr; + // A non-owned and possibly null pointer to shared RNG + RandomNumberGenerator* m_underlying_rng = nullptr; - // A non-owned and possibly null pointer to a shared Entropy_Source - Entropy_Sources* m_entropy_sources = nullptr; + // A non-owned and possibly null pointer to a shared Entropy_Source + Entropy_Sources* m_entropy_sources = nullptr; - const size_t m_reseed_interval; - uint32_t m_last_pid = 0; + const size_t m_reseed_interval; + uint32_t m_last_pid = 0; - /* - * Set to 1 after a successful seeding, then incremented. Reset - * to 0 by clear() or a fork. This logic is used even if - * automatic reseeding is disabled (via m_reseed_interval = 0) - */ - size_t m_reseed_counter = 0; - }; + /* + * Set to 1 after a successful seeding, then incremented. Reset + * to 0 by clear() or a fork. This logic is used even if + * automatic reseeding is disabled (via m_reseed_interval = 0) + */ + size_t m_reseed_counter = 0; +}; -} +} // namespace Botan namespace Botan { class Entropy_Sources; /** -* HMAC_DRBG from NIST SP800-90A -*/ -class BOTAN_PUBLIC_API(2,0) HMAC_DRBG final : public Stateful_RNG - { + * HMAC_DRBG from NIST SP800-90A + */ +class BOTAN_PUBLIC_API(2, 0) HMAC_DRBG final : public Stateful_RNG { public: - /** - * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) - * - * Automatic reseeding is disabled completely, as it has no access to - * any source for seed material. - * - * If a fork is detected, the RNG will be unable to reseed itself - * in response. In this case, an exception will be thrown rather - * than generating duplicated output. - */ - explicit HMAC_DRBG(std::unique_ptr prf); + /** + * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) + * + * Automatic reseeding is disabled completely, as it has no access to + * any source for seed material. + * + * If a fork is detected, the RNG will be unable to reseed itself + * in response. In this case, an exception will be thrown rather + * than generating duplicated output. + */ + explicit HMAC_DRBG(std::unique_ptr prf); - /** - * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) - * - * Automatic reseeding from @p underlying_rng will take place after - * @p reseed_interval many requests or after a fork was detected. - * - * @param prf MAC to use as a PRF - * @param underlying_rng is a reference to some RNG which will be used - * to perform the periodic reseeding - * @param reseed_interval specifies a limit of how many times - * the RNG will be called before automatic reseeding is performed - * @param max_number_of_bytes_per_request requests that are in size higher - * than max_number_of_bytes_per_request are treated as if multiple single - * requests of max_number_of_bytes_per_request size had been made. - * In theory SP 800-90A requires that we reject any request for a DRBG - * output longer than max_number_of_bytes_per_request. To avoid inconveniencing - * the caller who wants an output larger than max_number_of_bytes_per_request, - * instead treat these requests as if multiple requests of - * max_number_of_bytes_per_request size had been made. NIST requires for - * HMAC_DRBG that every implementation set a value no more than 2**19 bits - * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for - * example every 512 bit automatic reseeding occurs. - */ - HMAC_DRBG(std::unique_ptr prf, - RandomNumberGenerator& underlying_rng, - size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, - size_t max_number_of_bytes_per_request = 64 * 1024); + /** + * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) + * + * Automatic reseeding from @p underlying_rng will take place after + * @p reseed_interval many requests or after a fork was detected. + * + * @param prf MAC to use as a PRF + * @param underlying_rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. + */ + HMAC_DRBG(std::unique_ptr prf, RandomNumberGenerator& underlying_rng, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); - /** - * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) - * - * Automatic reseeding from @p entropy_sources will take place after - * @p reseed_interval many requests or after a fork was detected. - * - * @param prf MAC to use as a PRF - * @param entropy_sources will be polled to perform reseeding periodically - * @param reseed_interval specifies a limit of how many times - * the RNG will be called before automatic reseeding is performed. - * @param max_number_of_bytes_per_request requests that are in size higher - * than max_number_of_bytes_per_request are treated as if multiple single - * requests of max_number_of_bytes_per_request size had been made. - * In theory SP 800-90A requires that we reject any request for a DRBG - * output longer than max_number_of_bytes_per_request. To avoid inconveniencing - * the caller who wants an output larger than max_number_of_bytes_per_request, - * instead treat these requests as if multiple requests of - * max_number_of_bytes_per_request size had been made. NIST requires for - * HMAC_DRBG that every implementation set a value no more than 2**19 bits - * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for - * example every 512 bit automatic reseeding occurs. - */ - HMAC_DRBG(std::unique_ptr prf, - Entropy_Sources& entropy_sources, - size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, - size_t max_number_of_bytes_per_request = 64 * 1024); + /** + * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) + * + * Automatic reseeding from @p entropy_sources will take place after + * @p reseed_interval many requests or after a fork was detected. + * + * @param prf MAC to use as a PRF + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed. + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. + */ + HMAC_DRBG(std::unique_ptr prf, Entropy_Sources& entropy_sources, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); - /** - * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) - * - * Automatic reseeding from @p underlying_rng and @p entropy_sources - * will take place after @p reseed_interval many requests or after - * a fork was detected. - * - * @param prf MAC to use as a PRF - * @param underlying_rng is a reference to some RNG which will be used - * to perform the periodic reseeding - * @param entropy_sources will be polled to perform reseeding periodically - * @param reseed_interval specifies a limit of how many times - * the RNG will be called before automatic reseeding is performed. - * @param max_number_of_bytes_per_request requests that are in size higher - * than max_number_of_bytes_per_request are treated as if multiple single - * requests of max_number_of_bytes_per_request size had been made. - * In theory SP 800-90A requires that we reject any request for a DRBG - * output longer than max_number_of_bytes_per_request. To avoid inconveniencing - * the caller who wants an output larger than max_number_of_bytes_per_request, - * instead treat these requests as if multiple requests of - * max_number_of_bytes_per_request size had been made. NIST requires for - * HMAC_DRBG that every implementation set a value no more than 2**19 bits - * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for - * example every 512 bit automatic reseeding occurs. - */ - HMAC_DRBG(std::unique_ptr prf, - RandomNumberGenerator& underlying_rng, - Entropy_Sources& entropy_sources, - size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, - size_t max_number_of_bytes_per_request = 64 * 1024); + /** + * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) + * + * Automatic reseeding from @p underlying_rng and @p entropy_sources + * will take place after @p reseed_interval many requests or after + * a fork was detected. + * + * @param prf MAC to use as a PRF + * @param underlying_rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed. + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. + */ + HMAC_DRBG(std::unique_ptr prf, RandomNumberGenerator& underlying_rng, + Entropy_Sources& entropy_sources, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); - /** - * Constructor taking a string for the hash - */ - explicit HMAC_DRBG(const std::string& hmac_hash) : - Stateful_RNG(), - m_mac(MessageAuthenticationCode::create_or_throw("HMAC(" + hmac_hash + ")")), - m_max_number_of_bytes_per_request(64 * 1024) - { - clear(); - } - - std::string name() const override; - - void clear() override; - - void randomize(uint8_t output[], size_t output_len) override; - - void randomize_with_input(uint8_t output[], size_t output_len, - const uint8_t input[], size_t input_len) override; - - void add_entropy(const uint8_t input[], size_t input_len) override; - - size_t security_level() const override; - - size_t max_number_of_bytes_per_request() const override - { return m_max_number_of_bytes_per_request; } - - private: - void update(const uint8_t input[], size_t input_len); - - std::unique_ptr m_mac; - secure_vector m_V; - const size_t m_max_number_of_bytes_per_request; - }; - -} - -namespace Botan { - -/** -* Key Derivation Function -*/ -class BOTAN_PUBLIC_API(2,0) KDF - { - public: - virtual ~KDF() = default; - - /** - * Create an instance based on a name - * If provider is empty then best available is chosen. - * @param algo_spec algorithm name - * @param provider provider implementation to choose - * @return a null pointer if the algo/provider combination cannot be found - */ - static std::unique_ptr - create(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * Create an instance based on a name, or throw if the - * algo/provider combination cannot be found. If provider is - * empty then best available is chosen. - */ - static std::unique_ptr - create_or_throw(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @return list of available providers for this algorithm, empty if not available - */ - static std::vector providers(const std::string& algo_spec); - - /** - * @return KDF name - */ - virtual std::string name() const = 0; - - /** - * Derive a key - * @param key buffer holding the derived key, must be of length key_len - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param secret_len size of secret in bytes - * @param salt a diversifier - * @param salt_len size of salt in bytes - * @param label purpose for the derived keying material - * @param label_len size of label in bytes - * @return the derived key - */ - virtual size_t kdf(uint8_t key[], size_t key_len, - const uint8_t secret[], size_t secret_len, - const uint8_t salt[], size_t salt_len, - const uint8_t label[], size_t label_len) const = 0; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param secret_len size of secret in bytes - * @param salt a diversifier - * @param salt_len size of salt in bytes - * @param label purpose for the derived keying material - * @param label_len size of label in bytes - * @return the derived key - */ - secure_vector derive_key(size_t key_len, - const uint8_t secret[], - size_t secret_len, - const uint8_t salt[], - size_t salt_len, - const uint8_t label[] = nullptr, - size_t label_len = 0) const - { - secure_vector key(key_len); - key.resize(kdf(key.data(), key.size(), secret, secret_len, salt, salt_len, label, label_len)); - return key; - } - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - * @param label purpose for the derived keying material - * @return the derived key - */ - secure_vector derive_key(size_t key_len, - const secure_vector& secret, - const std::string& salt = "", - const std::string& label = "") const - { - return derive_key(key_len, secret.data(), secret.size(), - cast_char_ptr_to_uint8(salt.data()), - salt.length(), - cast_char_ptr_to_uint8(label.data()), - label.length()); - - } - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - * @param label purpose for the derived keying material - * @return the derived key - */ - template - secure_vector derive_key(size_t key_len, - const std::vector& secret, - const std::vector& salt, - const std::vector& label) const - { - return derive_key(key_len, - secret.data(), secret.size(), - salt.data(), salt.size(), - label.data(), label.size()); - } - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - * @param salt_len size of salt in bytes - * @param label purpose for the derived keying material - * @return the derived key - */ - secure_vector derive_key(size_t key_len, - const secure_vector& secret, - const uint8_t salt[], - size_t salt_len, - const std::string& label = "") const - { - return derive_key(key_len, - secret.data(), secret.size(), - salt, salt_len, - cast_char_ptr_to_uint8(label.data()), - label.size()); - } - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param secret_len size of secret in bytes - * @param salt a diversifier - * @param label purpose for the derived keying material - * @return the derived key - */ - secure_vector derive_key(size_t key_len, - const uint8_t secret[], - size_t secret_len, - const std::string& salt = "", - const std::string& label = "") const - { - return derive_key(key_len, secret, secret_len, - cast_char_ptr_to_uint8(salt.data()), - salt.length(), - cast_char_ptr_to_uint8(label.data()), - label.length()); - } - - /** - * @return new object representing the same algorithm as *this - */ - virtual KDF* clone() const = 0; - }; - -/** -* Factory method for KDF (key derivation function) -* @param algo_spec the name of the KDF to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_PUBLIC_API(2,0) KDF* get_kdf(const std::string& algo_spec); - -} - -//BOTAN_FUTURE_INTERNAL_HEADER(kdf2.h) - -namespace Botan { - -/** -* KDF2, from IEEE 1363 -*/ -class BOTAN_PUBLIC_API(2,0) KDF2 final : public KDF - { - public: - std::string name() const override { return "KDF2(" + m_hash->name() + ")"; } - - KDF* clone() const override { return new KDF2(m_hash->clone()); } - - size_t kdf(uint8_t key[], size_t key_len, - const uint8_t secret[], size_t secret_len, - const uint8_t salt[], size_t salt_len, - const uint8_t label[], size_t label_len) const override; - - /** - * @param h hash function to use - */ - explicit KDF2(HashFunction* h) : m_hash(h) {} - private: - std::unique_ptr m_hash; - }; - -} - -//BOTAN_FUTURE_INTERNAL_HEADER(loadstor.h) - -#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - #define BOTAN_ENDIAN_N2L(x) reverse_bytes(x) - #define BOTAN_ENDIAN_L2N(x) reverse_bytes(x) - #define BOTAN_ENDIAN_N2B(x) (x) - #define BOTAN_ENDIAN_B2N(x) (x) - -#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - #define BOTAN_ENDIAN_N2L(x) (x) - #define BOTAN_ENDIAN_L2N(x) (x) - #define BOTAN_ENDIAN_N2B(x) reverse_bytes(x) - #define BOTAN_ENDIAN_B2N(x) reverse_bytes(x) - -#endif - -namespace Botan { - -/** -* Byte extraction -* @param byte_num which byte to extract, 0 == highest byte -* @param input the value to extract from -* @return byte byte_num of input -*/ -template inline constexpr uint8_t get_byte(size_t byte_num, T input) - { - return static_cast( - input >> (((~byte_num)&(sizeof(T)-1)) << 3) - ); - } - -/** -* Make a uint16_t from two bytes -* @param i0 the first byte -* @param i1 the second byte -* @return i0 || i1 -*/ -inline constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1) - { - return static_cast((static_cast(i0) << 8) | i1); - } - -/** -* Make a uint32_t from four bytes -* @param i0 the first byte -* @param i1 the second byte -* @param i2 the third byte -* @param i3 the fourth byte -* @return i0 || i1 || i2 || i3 -*/ -inline constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3) - { - return ((static_cast(i0) << 24) | - (static_cast(i1) << 16) | - (static_cast(i2) << 8) | - (static_cast(i3))); - } - -/** -* Make a uint64_t from eight bytes -* @param i0 the first byte -* @param i1 the second byte -* @param i2 the third byte -* @param i3 the fourth byte -* @param i4 the fifth byte -* @param i5 the sixth byte -* @param i6 the seventh byte -* @param i7 the eighth byte -* @return i0 || i1 || i2 || i3 || i4 || i5 || i6 || i7 -*/ -inline constexpr uint64_t make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3, - uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7) - { - return ((static_cast(i0) << 56) | - (static_cast(i1) << 48) | - (static_cast(i2) << 40) | - (static_cast(i3) << 32) | - (static_cast(i4) << 24) | - (static_cast(i5) << 16) | - (static_cast(i6) << 8) | - (static_cast(i7))); + /** + * Constructor taking a string for the hash + */ + explicit HMAC_DRBG(const std::string& hmac_hash) + : Stateful_RNG(), + m_mac(MessageAuthenticationCode::create_or_throw("HMAC(" + hmac_hash + ")")), + m_max_number_of_bytes_per_request(64 * 1024) { + clear(); } -/** -* Load a big-endian word -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th T of in, as a big-endian value -*/ -template -inline T load_be(const uint8_t in[], size_t off) - { - in += off * sizeof(T); - T out = 0; - for(size_t i = 0; i != sizeof(T); ++i) - out = static_cast((out << 8) | in[i]); - return out; - } + std::string name() const override; -/** -* Load a little-endian word -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th T of in, as a litte-endian value -*/ -template -inline T load_le(const uint8_t in[], size_t off) - { - in += off * sizeof(T); - T out = 0; - for(size_t i = 0; i != sizeof(T); ++i) - out = (out << 8) | in[sizeof(T)-1-i]; - return out; - } + void clear() override; -/** -* Load a big-endian uint16_t -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th uint16_t of in, as a big-endian value -*/ -template<> -inline uint16_t load_be(const uint8_t in[], size_t off) - { - in += off * sizeof(uint16_t); + void randomize(uint8_t output[], size_t output_len) override; -#if defined(BOTAN_ENDIAN_N2B) - uint16_t x; - typecast_copy(x, in); - return BOTAN_ENDIAN_N2B(x); -#else - return make_uint16(in[0], in[1]); -#endif - } + void randomize_with_input(uint8_t output[], size_t output_len, const uint8_t input[], + size_t input_len) override; -/** -* Load a little-endian uint16_t -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th uint16_t of in, as a little-endian value -*/ -template<> -inline uint16_t load_le(const uint8_t in[], size_t off) - { - in += off * sizeof(uint16_t); + void add_entropy(const uint8_t input[], size_t input_len) override; -#if defined(BOTAN_ENDIAN_N2L) - uint16_t x; - typecast_copy(x, in); - return BOTAN_ENDIAN_N2L(x); -#else - return make_uint16(in[1], in[0]); -#endif - } + size_t security_level() const override; -/** -* Load a big-endian uint32_t -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th uint32_t of in, as a big-endian value -*/ -template<> -inline uint32_t load_be(const uint8_t in[], size_t off) - { - in += off * sizeof(uint32_t); -#if defined(BOTAN_ENDIAN_N2B) - uint32_t x; - typecast_copy(x, in); - return BOTAN_ENDIAN_N2B(x); -#else - return make_uint32(in[0], in[1], in[2], in[3]); -#endif - } + size_t max_number_of_bytes_per_request() const override { + return m_max_number_of_bytes_per_request; + } -/** -* Load a little-endian uint32_t -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th uint32_t of in, as a little-endian value -*/ -template<> -inline uint32_t load_le(const uint8_t in[], size_t off) - { - in += off * sizeof(uint32_t); -#if defined(BOTAN_ENDIAN_N2L) - uint32_t x; - typecast_copy(x, in); - return BOTAN_ENDIAN_N2L(x); -#else - return make_uint32(in[3], in[2], in[1], in[0]); -#endif - } + private: + void update(const uint8_t input[], size_t input_len); -/** -* Load a big-endian uint64_t -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th uint64_t of in, as a big-endian value -*/ -template<> -inline uint64_t load_be(const uint8_t in[], size_t off) - { - in += off * sizeof(uint64_t); -#if defined(BOTAN_ENDIAN_N2B) - uint64_t x; - typecast_copy(x, in); - return BOTAN_ENDIAN_N2B(x); -#else - return make_uint64(in[0], in[1], in[2], in[3], - in[4], in[5], in[6], in[7]); -#endif - } + std::unique_ptr m_mac; + secure_vector m_V; + const size_t m_max_number_of_bytes_per_request; +}; -/** -* Load a little-endian uint64_t -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th uint64_t of in, as a little-endian value -*/ -template<> -inline uint64_t load_le(const uint8_t in[], size_t off) - { - in += off * sizeof(uint64_t); -#if defined(BOTAN_ENDIAN_N2L) - uint64_t x; - typecast_copy(x, in); - return BOTAN_ENDIAN_N2L(x); -#else - return make_uint64(in[7], in[6], in[5], in[4], - in[3], in[2], in[1], in[0]); -#endif - } - -/** -* Load two little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -*/ -template -inline void load_le(const uint8_t in[], T& x0, T& x1) - { - x0 = load_le(in, 0); - x1 = load_le(in, 1); - } - -/** -* Load four little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -*/ -template -inline void load_le(const uint8_t in[], - T& x0, T& x1, T& x2, T& x3) - { - x0 = load_le(in, 0); - x1 = load_le(in, 1); - x2 = load_le(in, 2); - x3 = load_le(in, 3); - } - -/** -* Load eight little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -* @param x4 where the fifth word will be written -* @param x5 where the sixth word will be written -* @param x6 where the seventh word will be written -* @param x7 where the eighth word will be written -*/ -template -inline void load_le(const uint8_t in[], - T& x0, T& x1, T& x2, T& x3, - T& x4, T& x5, T& x6, T& x7) - { - x0 = load_le(in, 0); - x1 = load_le(in, 1); - x2 = load_le(in, 2); - x3 = load_le(in, 3); - x4 = load_le(in, 4); - x5 = load_le(in, 5); - x6 = load_le(in, 6); - x7 = load_le(in, 7); - } - -/** -* Load a variable number of little-endian words -* @param out the output array of words -* @param in the input array of bytes -* @param count how many words are in in -*/ -template -inline void load_le(T out[], - const uint8_t in[], - size_t count) - { - if(count > 0) - { -#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - typecast_copy(out, in, count); - -#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - typecast_copy(out, in, count); - - const size_t blocks = count - (count % 4); - const size_t left = count - blocks; - - for(size_t i = 0; i != blocks; i += 4) - bswap_4(out + i); - - for(size_t i = 0; i != left; ++i) - out[blocks+i] = reverse_bytes(out[blocks+i]); -#else - for(size_t i = 0; i != count; ++i) - out[i] = load_le(in, i); -#endif - } - } - -/** -* Load two big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -*/ -template -inline void load_be(const uint8_t in[], T& x0, T& x1) - { - x0 = load_be(in, 0); - x1 = load_be(in, 1); - } - -/** -* Load four big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -*/ -template -inline void load_be(const uint8_t in[], - T& x0, T& x1, T& x2, T& x3) - { - x0 = load_be(in, 0); - x1 = load_be(in, 1); - x2 = load_be(in, 2); - x3 = load_be(in, 3); - } - -/** -* Load eight big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -* @param x4 where the fifth word will be written -* @param x5 where the sixth word will be written -* @param x6 where the seventh word will be written -* @param x7 where the eighth word will be written -*/ -template -inline void load_be(const uint8_t in[], - T& x0, T& x1, T& x2, T& x3, - T& x4, T& x5, T& x6, T& x7) - { - x0 = load_be(in, 0); - x1 = load_be(in, 1); - x2 = load_be(in, 2); - x3 = load_be(in, 3); - x4 = load_be(in, 4); - x5 = load_be(in, 5); - x6 = load_be(in, 6); - x7 = load_be(in, 7); - } - -/** -* Load a variable number of big-endian words -* @param out the output array of words -* @param in the input array of bytes -* @param count how many words are in in -*/ -template -inline void load_be(T out[], - const uint8_t in[], - size_t count) - { - if(count > 0) - { -#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - typecast_copy(out, in, count); - -#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - typecast_copy(out, in, count); - const size_t blocks = count - (count % 4); - const size_t left = count - blocks; - - for(size_t i = 0; i != blocks; i += 4) - bswap_4(out + i); - - for(size_t i = 0; i != left; ++i) - out[blocks+i] = reverse_bytes(out[blocks+i]); -#else - for(size_t i = 0; i != count; ++i) - out[i] = load_be(in, i); -#endif - } - } - -/** -* Store a big-endian uint16_t -* @param in the input uint16_t -* @param out the byte array to write to -*/ -inline void store_be(uint16_t in, uint8_t out[2]) - { -#if defined(BOTAN_ENDIAN_N2B) - uint16_t o = BOTAN_ENDIAN_N2B(in); - typecast_copy(out, o); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); -#endif - } - -/** -* Store a little-endian uint16_t -* @param in the input uint16_t -* @param out the byte array to write to -*/ -inline void store_le(uint16_t in, uint8_t out[2]) - { -#if defined(BOTAN_ENDIAN_N2L) - uint16_t o = BOTAN_ENDIAN_N2L(in); - typecast_copy(out, o); -#else - out[0] = get_byte(1, in); - out[1] = get_byte(0, in); -#endif - } - -/** -* Store a big-endian uint32_t -* @param in the input uint32_t -* @param out the byte array to write to -*/ -inline void store_be(uint32_t in, uint8_t out[4]) - { -#if defined(BOTAN_ENDIAN_B2N) - uint32_t o = BOTAN_ENDIAN_B2N(in); - typecast_copy(out, o); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); - out[2] = get_byte(2, in); - out[3] = get_byte(3, in); -#endif - } - -/** -* Store a little-endian uint32_t -* @param in the input uint32_t -* @param out the byte array to write to -*/ -inline void store_le(uint32_t in, uint8_t out[4]) - { -#if defined(BOTAN_ENDIAN_L2N) - uint32_t o = BOTAN_ENDIAN_L2N(in); - typecast_copy(out, o); -#else - out[0] = get_byte(3, in); - out[1] = get_byte(2, in); - out[2] = get_byte(1, in); - out[3] = get_byte(0, in); -#endif - } - -/** -* Store a big-endian uint64_t -* @param in the input uint64_t -* @param out the byte array to write to -*/ -inline void store_be(uint64_t in, uint8_t out[8]) - { -#if defined(BOTAN_ENDIAN_B2N) - uint64_t o = BOTAN_ENDIAN_B2N(in); - typecast_copy(out, o); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); - out[2] = get_byte(2, in); - out[3] = get_byte(3, in); - out[4] = get_byte(4, in); - out[5] = get_byte(5, in); - out[6] = get_byte(6, in); - out[7] = get_byte(7, in); -#endif - } - -/** -* Store a little-endian uint64_t -* @param in the input uint64_t -* @param out the byte array to write to -*/ -inline void store_le(uint64_t in, uint8_t out[8]) - { -#if defined(BOTAN_ENDIAN_L2N) - uint64_t o = BOTAN_ENDIAN_L2N(in); - typecast_copy(out, o); -#else - out[0] = get_byte(7, in); - out[1] = get_byte(6, in); - out[2] = get_byte(5, in); - out[3] = get_byte(4, in); - out[4] = get_byte(3, in); - out[5] = get_byte(2, in); - out[6] = get_byte(1, in); - out[7] = get_byte(0, in); -#endif - } - -/** -* Store two little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -*/ -template -inline void store_le(uint8_t out[], T x0, T x1) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - } - -/** -* Store two big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -*/ -template -inline void store_be(uint8_t out[], T x0, T x1) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - } - -/** -* Store four little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -*/ -template -inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - store_le(x2, out + (2 * sizeof(T))); - store_le(x3, out + (3 * sizeof(T))); - } - -/** -* Store four big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -*/ -template -inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - store_be(x2, out + (2 * sizeof(T))); - store_be(x3, out + (3 * sizeof(T))); - } - -/** -* Store eight little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -* @param x4 the fifth word -* @param x5 the sixth word -* @param x6 the seventh word -* @param x7 the eighth word -*/ -template -inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3, - T x4, T x5, T x6, T x7) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - store_le(x2, out + (2 * sizeof(T))); - store_le(x3, out + (3 * sizeof(T))); - store_le(x4, out + (4 * sizeof(T))); - store_le(x5, out + (5 * sizeof(T))); - store_le(x6, out + (6 * sizeof(T))); - store_le(x7, out + (7 * sizeof(T))); - } - -/** -* Store eight big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -* @param x4 the fifth word -* @param x5 the sixth word -* @param x6 the seventh word -* @param x7 the eighth word -*/ -template -inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3, - T x4, T x5, T x6, T x7) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - store_be(x2, out + (2 * sizeof(T))); - store_be(x3, out + (3 * sizeof(T))); - store_be(x4, out + (4 * sizeof(T))); - store_be(x5, out + (5 * sizeof(T))); - store_be(x6, out + (6 * sizeof(T))); - store_be(x7, out + (7 * sizeof(T))); - } - -template -void copy_out_be(uint8_t out[], size_t out_bytes, const T in[]) - { - while(out_bytes >= sizeof(T)) - { - store_be(in[0], out); - out += sizeof(T); - out_bytes -= sizeof(T); - in += 1; - } - - for(size_t i = 0; i != out_bytes; ++i) - out[i] = get_byte(i%8, in[0]); - } - -template -void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector& in) - { - copy_out_be(out, out_bytes, in.data()); - } - -template -void copy_out_le(uint8_t out[], size_t out_bytes, const T in[]) - { - while(out_bytes >= sizeof(T)) - { - store_le(in[0], out); - out += sizeof(T); - out_bytes -= sizeof(T); - in += 1; - } - - for(size_t i = 0; i != out_bytes; ++i) - out[i] = get_byte(sizeof(T) - 1 - (i % 8), in[0]); - } - -template -void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector& in) - { - copy_out_le(out, out_bytes, in.data()); - } - -} - -//BOTAN_FUTURE_INTERNAL_HEADER(mdx_hash.h) +} // namespace Botan namespace Botan { /** -* MDx Hash Function Base Class -*/ -class BOTAN_PUBLIC_API(2,0) MDx_HashFunction : public HashFunction - { + * Key Derivation Function + */ +class BOTAN_PUBLIC_API(2, 0) KDF { public: - /** - * @param block_length is the number of bytes per block, which must - * be a power of 2 and at least 8. - * @param big_byte_endian specifies if the hash uses big-endian bytes - * @param big_bit_endian specifies if the hash uses big-endian bits - * @param counter_size specifies the size of the counter var in bytes - */ - MDx_HashFunction(size_t block_length, - bool big_byte_endian, - bool big_bit_endian, - uint8_t counter_size = 8); + virtual ~KDF() = default; - size_t hash_block_size() const override final { return m_buffer.size(); } - protected: - void add_data(const uint8_t input[], size_t length) override final; - void final_result(uint8_t output[]) override final; + /** + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to choose + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr create(const std::string& algo_spec, + const std::string& provider = ""); - /** - * Run the hash's compression function over a set of blocks - * @param blocks the input - * @param block_n the number of blocks - */ - virtual void compress_n(const uint8_t blocks[], size_t block_n) = 0; + /** + * Create an instance based on a name, or throw if the + * algo/provider combination cannot be found. If provider is + * empty then best available is chosen. + */ + static std::unique_ptr create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); - void clear() override; + /** + * @return list of available providers for this algorithm, empty if not available + */ + static std::vector providers(const std::string& algo_spec); - /** - * Copy the output to the buffer - * @param buffer to put the output into - */ - virtual void copy_out(uint8_t buffer[]) = 0; + /** + * @return KDF name + */ + virtual std::string name() const = 0; + + /** + * Derive a key + * @param key buffer holding the derived key, must be of length key_len + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + * @param salt_len size of salt in bytes + * @param label purpose for the derived keying material + * @param label_len size of label in bytes + * @return the derived key + */ + virtual size_t kdf(uint8_t key[], size_t key_len, const uint8_t secret[], size_t secret_len, + const uint8_t salt[], size_t salt_len, const uint8_t label[], + size_t label_len) const = 0; + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + * @param salt_len size of salt in bytes + * @param label purpose for the derived keying material + * @param label_len size of label in bytes + * @return the derived key + */ + secure_vector derive_key(size_t key_len, const uint8_t secret[], size_t secret_len, + const uint8_t salt[], size_t salt_len, + const uint8_t label[] = nullptr, size_t label_len = 0) const { + secure_vector key(key_len); + key.resize( + kdf(key.data(), key.size(), secret, secret_len, salt, salt_len, label, label_len)); + return key; + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + * @param label purpose for the derived keying material + * @return the derived key + */ + secure_vector derive_key(size_t key_len, const secure_vector& secret, + const std::string& salt = "", + const std::string& label = "") const { + return derive_key(key_len, secret.data(), secret.size(), + cast_char_ptr_to_uint8(salt.data()), salt.length(), + cast_char_ptr_to_uint8(label.data()), label.length()); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + * @param label purpose for the derived keying material + * @return the derived key + */ + template + secure_vector derive_key(size_t key_len, const std::vector& secret, + const std::vector& salt, + const std::vector& label) const { + return derive_key(key_len, secret.data(), secret.size(), salt.data(), salt.size(), + label.data(), label.size()); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + * @param salt_len size of salt in bytes + * @param label purpose for the derived keying material + * @return the derived key + */ + secure_vector derive_key(size_t key_len, const secure_vector& secret, + const uint8_t salt[], size_t salt_len, + const std::string& label = "") const { + return derive_key(key_len, secret.data(), secret.size(), salt, salt_len, + cast_char_ptr_to_uint8(label.data()), label.size()); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + * @param label purpose for the derived keying material + * @return the derived key + */ + secure_vector derive_key(size_t key_len, const uint8_t secret[], size_t secret_len, + const std::string& salt = "", + const std::string& label = "") const { + return derive_key(key_len, secret, secret_len, cast_char_ptr_to_uint8(salt.data()), + salt.length(), cast_char_ptr_to_uint8(label.data()), label.length()); + } + + /** + * @return new object representing the same algorithm as *this + */ + virtual KDF* clone() const = 0; +}; + +/** + * Factory method for KDF (key derivation function) + * @param algo_spec the name of the KDF to create + * @return pointer to newly allocated object of that type + */ +BOTAN_PUBLIC_API(2, 0) KDF* get_kdf(const std::string& algo_spec); + +} // namespace Botan + +// BOTAN_FUTURE_INTERNAL_HEADER(kdf2.h) + +namespace Botan { + +/** + * KDF2, from IEEE 1363 + */ +class BOTAN_PUBLIC_API(2, 0) KDF2 final : public KDF { + public: + std::string name() const override { return "KDF2(" + m_hash->name() + ")"; } + + KDF* clone() const override { return new KDF2(m_hash->clone()); } + + size_t kdf(uint8_t key[], size_t key_len, const uint8_t secret[], size_t secret_len, + const uint8_t salt[], size_t salt_len, const uint8_t label[], + size_t label_len) const override; + + /** + * @param h hash function to use + */ + explicit KDF2(HashFunction* h) : m_hash(h) {} - /** - * Write the count, if used, to this spot - * @param out where to write the counter to - */ - virtual void write_count(uint8_t out[]); private: - const uint8_t m_pad_char; - const uint8_t m_counter_size; - const uint8_t m_block_bits; - const bool m_count_big_endian; + std::unique_ptr m_hash; +}; - uint64_t m_count; - secure_vector m_buffer; - size_t m_position; - }; +} // namespace Botan +// BOTAN_FUTURE_INTERNAL_HEADER(loadstor.h) + +#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) +#define BOTAN_ENDIAN_N2L(x) reverse_bytes(x) +#define BOTAN_ENDIAN_L2N(x) reverse_bytes(x) +#define BOTAN_ENDIAN_N2B(x) (x) +#define BOTAN_ENDIAN_B2N(x) (x) + +#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) +#define BOTAN_ENDIAN_N2L(x) (x) +#define BOTAN_ENDIAN_L2N(x) (x) +#define BOTAN_ENDIAN_N2B(x) reverse_bytes(x) +#define BOTAN_ENDIAN_B2N(x) reverse_bytes(x) + +#endif + +namespace Botan { + +/** + * Byte extraction + * @param byte_num which byte to extract, 0 == highest byte + * @param input the value to extract from + * @return byte byte_num of input + */ +template +inline constexpr uint8_t get_byte(size_t byte_num, T input) { + return static_cast(input >> (((~byte_num) & (sizeof(T) - 1)) << 3)); } +/** + * Make a uint16_t from two bytes + * @param i0 the first byte + * @param i1 the second byte + * @return i0 || i1 + */ +inline constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1) { + return static_cast((static_cast(i0) << 8) | i1); +} + +/** + * Make a uint32_t from four bytes + * @param i0 the first byte + * @param i1 the second byte + * @param i2 the third byte + * @param i3 the fourth byte + * @return i0 || i1 || i2 || i3 + */ +inline constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3) { + return ((static_cast(i0) << 24) | (static_cast(i1) << 16) | + (static_cast(i2) << 8) | (static_cast(i3))); +} + +/** + * Make a uint64_t from eight bytes + * @param i0 the first byte + * @param i1 the second byte + * @param i2 the third byte + * @param i3 the fourth byte + * @param i4 the fifth byte + * @param i5 the sixth byte + * @param i6 the seventh byte + * @param i7 the eighth byte + * @return i0 || i1 || i2 || i3 || i4 || i5 || i6 || i7 + */ +inline constexpr uint64_t make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4, + uint8_t i5, uint8_t i6, uint8_t i7) { + return ((static_cast(i0) << 56) | (static_cast(i1) << 48) | + (static_cast(i2) << 40) | (static_cast(i3) << 32) | + (static_cast(i4) << 24) | (static_cast(i5) << 16) | + (static_cast(i6) << 8) | (static_cast(i7))); +} + +/** + * Load a big-endian word + * @param in a pointer to some bytes + * @param off an offset into the array + * @return off'th T of in, as a big-endian value + */ +template +inline T load_be(const uint8_t in[], size_t off) { + in += off * sizeof(T); + T out = 0; + for (size_t i = 0; i != sizeof(T); ++i) out = static_cast((out << 8) | in[i]); + return out; +} + +/** + * Load a little-endian word + * @param in a pointer to some bytes + * @param off an offset into the array + * @return off'th T of in, as a litte-endian value + */ +template +inline T load_le(const uint8_t in[], size_t off) { + in += off * sizeof(T); + T out = 0; + for (size_t i = 0; i != sizeof(T); ++i) out = (out << 8) | in[sizeof(T) - 1 - i]; + return out; +} + +/** + * Load a big-endian uint16_t + * @param in a pointer to some bytes + * @param off an offset into the array + * @return off'th uint16_t of in, as a big-endian value + */ +template <> +inline uint16_t load_be(const uint8_t in[], size_t off) { + in += off * sizeof(uint16_t); + +#if defined(BOTAN_ENDIAN_N2B) + uint16_t x; + typecast_copy(x, in); + return BOTAN_ENDIAN_N2B(x); +#else + return make_uint16(in[0], in[1]); +#endif +} + +/** + * Load a little-endian uint16_t + * @param in a pointer to some bytes + * @param off an offset into the array + * @return off'th uint16_t of in, as a little-endian value + */ +template <> +inline uint16_t load_le(const uint8_t in[], size_t off) { + in += off * sizeof(uint16_t); + +#if defined(BOTAN_ENDIAN_N2L) + uint16_t x; + typecast_copy(x, in); + return BOTAN_ENDIAN_N2L(x); +#else + return make_uint16(in[1], in[0]); +#endif +} + +/** + * Load a big-endian uint32_t + * @param in a pointer to some bytes + * @param off an offset into the array + * @return off'th uint32_t of in, as a big-endian value + */ +template <> +inline uint32_t load_be(const uint8_t in[], size_t off) { + in += off * sizeof(uint32_t); +#if defined(BOTAN_ENDIAN_N2B) + uint32_t x; + typecast_copy(x, in); + return BOTAN_ENDIAN_N2B(x); +#else + return make_uint32(in[0], in[1], in[2], in[3]); +#endif +} + +/** + * Load a little-endian uint32_t + * @param in a pointer to some bytes + * @param off an offset into the array + * @return off'th uint32_t of in, as a little-endian value + */ +template <> +inline uint32_t load_le(const uint8_t in[], size_t off) { + in += off * sizeof(uint32_t); +#if defined(BOTAN_ENDIAN_N2L) + uint32_t x; + typecast_copy(x, in); + return BOTAN_ENDIAN_N2L(x); +#else + return make_uint32(in[3], in[2], in[1], in[0]); +#endif +} + +/** + * Load a big-endian uint64_t + * @param in a pointer to some bytes + * @param off an offset into the array + * @return off'th uint64_t of in, as a big-endian value + */ +template <> +inline uint64_t load_be(const uint8_t in[], size_t off) { + in += off * sizeof(uint64_t); +#if defined(BOTAN_ENDIAN_N2B) + uint64_t x; + typecast_copy(x, in); + return BOTAN_ENDIAN_N2B(x); +#else + return make_uint64(in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]); +#endif +} + +/** + * Load a little-endian uint64_t + * @param in a pointer to some bytes + * @param off an offset into the array + * @return off'th uint64_t of in, as a little-endian value + */ +template <> +inline uint64_t load_le(const uint8_t in[], size_t off) { + in += off * sizeof(uint64_t); +#if defined(BOTAN_ENDIAN_N2L) + uint64_t x; + typecast_copy(x, in); + return BOTAN_ENDIAN_N2L(x); +#else + return make_uint64(in[7], in[6], in[5], in[4], in[3], in[2], in[1], in[0]); +#endif +} + +/** + * Load two little-endian words + * @param in a pointer to some bytes + * @param x0 where the first word will be written + * @param x1 where the second word will be written + */ +template +inline void load_le(const uint8_t in[], T& x0, T& x1) { + x0 = load_le(in, 0); + x1 = load_le(in, 1); +} + +/** + * Load four little-endian words + * @param in a pointer to some bytes + * @param x0 where the first word will be written + * @param x1 where the second word will be written + * @param x2 where the third word will be written + * @param x3 where the fourth word will be written + */ +template +inline void load_le(const uint8_t in[], T& x0, T& x1, T& x2, T& x3) { + x0 = load_le(in, 0); + x1 = load_le(in, 1); + x2 = load_le(in, 2); + x3 = load_le(in, 3); +} + +/** + * Load eight little-endian words + * @param in a pointer to some bytes + * @param x0 where the first word will be written + * @param x1 where the second word will be written + * @param x2 where the third word will be written + * @param x3 where the fourth word will be written + * @param x4 where the fifth word will be written + * @param x5 where the sixth word will be written + * @param x6 where the seventh word will be written + * @param x7 where the eighth word will be written + */ +template +inline void load_le(const uint8_t in[], T& x0, T& x1, T& x2, T& x3, T& x4, T& x5, T& x6, T& x7) { + x0 = load_le(in, 0); + x1 = load_le(in, 1); + x2 = load_le(in, 2); + x3 = load_le(in, 3); + x4 = load_le(in, 4); + x5 = load_le(in, 5); + x6 = load_le(in, 6); + x7 = load_le(in, 7); +} + +/** + * Load a variable number of little-endian words + * @param out the output array of words + * @param in the input array of bytes + * @param count how many words are in in + */ +template +inline void load_le(T out[], const uint8_t in[], size_t count) { + if (count > 0) { +#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) + typecast_copy(out, in, count); + +#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) + typecast_copy(out, in, count); + + const size_t blocks = count - (count % 4); + const size_t left = count - blocks; + + for (size_t i = 0; i != blocks; i += 4) bswap_4(out + i); + + for (size_t i = 0; i != left; ++i) out[blocks + i] = reverse_bytes(out[blocks + i]); +#else + for (size_t i = 0; i != count; ++i) out[i] = load_le(in, i); +#endif + } +} + +/** + * Load two big-endian words + * @param in a pointer to some bytes + * @param x0 where the first word will be written + * @param x1 where the second word will be written + */ +template +inline void load_be(const uint8_t in[], T& x0, T& x1) { + x0 = load_be(in, 0); + x1 = load_be(in, 1); +} + +/** + * Load four big-endian words + * @param in a pointer to some bytes + * @param x0 where the first word will be written + * @param x1 where the second word will be written + * @param x2 where the third word will be written + * @param x3 where the fourth word will be written + */ +template +inline void load_be(const uint8_t in[], T& x0, T& x1, T& x2, T& x3) { + x0 = load_be(in, 0); + x1 = load_be(in, 1); + x2 = load_be(in, 2); + x3 = load_be(in, 3); +} + +/** + * Load eight big-endian words + * @param in a pointer to some bytes + * @param x0 where the first word will be written + * @param x1 where the second word will be written + * @param x2 where the third word will be written + * @param x3 where the fourth word will be written + * @param x4 where the fifth word will be written + * @param x5 where the sixth word will be written + * @param x6 where the seventh word will be written + * @param x7 where the eighth word will be written + */ +template +inline void load_be(const uint8_t in[], T& x0, T& x1, T& x2, T& x3, T& x4, T& x5, T& x6, T& x7) { + x0 = load_be(in, 0); + x1 = load_be(in, 1); + x2 = load_be(in, 2); + x3 = load_be(in, 3); + x4 = load_be(in, 4); + x5 = load_be(in, 5); + x6 = load_be(in, 6); + x7 = load_be(in, 7); +} + +/** + * Load a variable number of big-endian words + * @param out the output array of words + * @param in the input array of bytes + * @param count how many words are in in + */ +template +inline void load_be(T out[], const uint8_t in[], size_t count) { + if (count > 0) { +#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) + typecast_copy(out, in, count); + +#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) + typecast_copy(out, in, count); + const size_t blocks = count - (count % 4); + const size_t left = count - blocks; + + for (size_t i = 0; i != blocks; i += 4) bswap_4(out + i); + + for (size_t i = 0; i != left; ++i) out[blocks + i] = reverse_bytes(out[blocks + i]); +#else + for (size_t i = 0; i != count; ++i) out[i] = load_be(in, i); +#endif + } +} + +/** + * Store a big-endian uint16_t + * @param in the input uint16_t + * @param out the byte array to write to + */ +inline void store_be(uint16_t in, uint8_t out[2]) { +#if defined(BOTAN_ENDIAN_N2B) + uint16_t o = BOTAN_ENDIAN_N2B(in); + typecast_copy(out, o); +#else + out[0] = get_byte(0, in); + out[1] = get_byte(1, in); +#endif +} + +/** + * Store a little-endian uint16_t + * @param in the input uint16_t + * @param out the byte array to write to + */ +inline void store_le(uint16_t in, uint8_t out[2]) { +#if defined(BOTAN_ENDIAN_N2L) + uint16_t o = BOTAN_ENDIAN_N2L(in); + typecast_copy(out, o); +#else + out[0] = get_byte(1, in); + out[1] = get_byte(0, in); +#endif +} + +/** + * Store a big-endian uint32_t + * @param in the input uint32_t + * @param out the byte array to write to + */ +inline void store_be(uint32_t in, uint8_t out[4]) { +#if defined(BOTAN_ENDIAN_B2N) + uint32_t o = BOTAN_ENDIAN_B2N(in); + typecast_copy(out, o); +#else + out[0] = get_byte(0, in); + out[1] = get_byte(1, in); + out[2] = get_byte(2, in); + out[3] = get_byte(3, in); +#endif +} + +/** + * Store a little-endian uint32_t + * @param in the input uint32_t + * @param out the byte array to write to + */ +inline void store_le(uint32_t in, uint8_t out[4]) { +#if defined(BOTAN_ENDIAN_L2N) + uint32_t o = BOTAN_ENDIAN_L2N(in); + typecast_copy(out, o); +#else + out[0] = get_byte(3, in); + out[1] = get_byte(2, in); + out[2] = get_byte(1, in); + out[3] = get_byte(0, in); +#endif +} + +/** + * Store a big-endian uint64_t + * @param in the input uint64_t + * @param out the byte array to write to + */ +inline void store_be(uint64_t in, uint8_t out[8]) { +#if defined(BOTAN_ENDIAN_B2N) + uint64_t o = BOTAN_ENDIAN_B2N(in); + typecast_copy(out, o); +#else + out[0] = get_byte(0, in); + out[1] = get_byte(1, in); + out[2] = get_byte(2, in); + out[3] = get_byte(3, in); + out[4] = get_byte(4, in); + out[5] = get_byte(5, in); + out[6] = get_byte(6, in); + out[7] = get_byte(7, in); +#endif +} + +/** + * Store a little-endian uint64_t + * @param in the input uint64_t + * @param out the byte array to write to + */ +inline void store_le(uint64_t in, uint8_t out[8]) { +#if defined(BOTAN_ENDIAN_L2N) + uint64_t o = BOTAN_ENDIAN_L2N(in); + typecast_copy(out, o); +#else + out[0] = get_byte(7, in); + out[1] = get_byte(6, in); + out[2] = get_byte(5, in); + out[3] = get_byte(4, in); + out[4] = get_byte(3, in); + out[5] = get_byte(2, in); + out[6] = get_byte(1, in); + out[7] = get_byte(0, in); +#endif +} + +/** + * Store two little-endian words + * @param out the output byte array + * @param x0 the first word + * @param x1 the second word + */ +template +inline void store_le(uint8_t out[], T x0, T x1) { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); +} + +/** + * Store two big-endian words + * @param out the output byte array + * @param x0 the first word + * @param x1 the second word + */ +template +inline void store_be(uint8_t out[], T x0, T x1) { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); +} + +/** + * Store four little-endian words + * @param out the output byte array + * @param x0 the first word + * @param x1 the second word + * @param x2 the third word + * @param x3 the fourth word + */ +template +inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3) { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); +} + +/** + * Store four big-endian words + * @param out the output byte array + * @param x0 the first word + * @param x1 the second word + * @param x2 the third word + * @param x3 the fourth word + */ +template +inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3) { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); +} + +/** + * Store eight little-endian words + * @param out the output byte array + * @param x0 the first word + * @param x1 the second word + * @param x2 the third word + * @param x3 the fourth word + * @param x4 the fifth word + * @param x5 the sixth word + * @param x6 the seventh word + * @param x7 the eighth word + */ +template +inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3, T x4, T x5, T x6, T x7) { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); + store_le(x4, out + (4 * sizeof(T))); + store_le(x5, out + (5 * sizeof(T))); + store_le(x6, out + (6 * sizeof(T))); + store_le(x7, out + (7 * sizeof(T))); +} + +/** + * Store eight big-endian words + * @param out the output byte array + * @param x0 the first word + * @param x1 the second word + * @param x2 the third word + * @param x3 the fourth word + * @param x4 the fifth word + * @param x5 the sixth word + * @param x6 the seventh word + * @param x7 the eighth word + */ +template +inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3, T x4, T x5, T x6, T x7) { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); + store_be(x4, out + (4 * sizeof(T))); + store_be(x5, out + (5 * sizeof(T))); + store_be(x6, out + (6 * sizeof(T))); + store_be(x7, out + (7 * sizeof(T))); +} + +template +void copy_out_be(uint8_t out[], size_t out_bytes, const T in[]) { + while (out_bytes >= sizeof(T)) { + store_be(in[0], out); + out += sizeof(T); + out_bytes -= sizeof(T); + in += 1; + } + + for (size_t i = 0; i != out_bytes; ++i) out[i] = get_byte(i % 8, in[0]); +} + +template +void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector& in) { + copy_out_be(out, out_bytes, in.data()); +} + +template +void copy_out_le(uint8_t out[], size_t out_bytes, const T in[]) { + while (out_bytes >= sizeof(T)) { + store_le(in[0], out); + out += sizeof(T); + out_bytes -= sizeof(T); + in += 1; + } + + for (size_t i = 0; i != out_bytes; ++i) out[i] = get_byte(sizeof(T) - 1 - (i % 8), in[0]); +} + +template +void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector& in) { + copy_out_le(out, out_bytes, in.data()); +} + +} // namespace Botan + +// BOTAN_FUTURE_INTERNAL_HEADER(mdx_hash.h) + +namespace Botan { + +/** + * MDx Hash Function Base Class + */ +class BOTAN_PUBLIC_API(2, 0) MDx_HashFunction : public HashFunction { + public: + /** + * @param block_length is the number of bytes per block, which must + * be a power of 2 and at least 8. + * @param big_byte_endian specifies if the hash uses big-endian bytes + * @param big_bit_endian specifies if the hash uses big-endian bits + * @param counter_size specifies the size of the counter var in bytes + */ + MDx_HashFunction(size_t block_length, bool big_byte_endian, bool big_bit_endian, + uint8_t counter_size = 8); + + size_t hash_block_size() const override final { return m_buffer.size(); } + + protected: + void add_data(const uint8_t input[], size_t length) override final; + void final_result(uint8_t output[]) override final; + + /** + * Run the hash's compression function over a set of blocks + * @param blocks the input + * @param block_n the number of blocks + */ + virtual void compress_n(const uint8_t blocks[], size_t block_n) = 0; + + void clear() override; + + /** + * Copy the output to the buffer + * @param buffer to put the output into + */ + virtual void copy_out(uint8_t buffer[]) = 0; + + /** + * Write the count, if used, to this spot + * @param out where to write the counter to + */ + virtual void write_count(uint8_t out[]); + + private: + const uint8_t m_pad_char; + const uint8_t m_counter_size; + const uint8_t m_block_bits; + const bool m_count_big_endian; + + uint64_t m_count; + secure_vector m_buffer; + size_t m_position; +}; + +} // namespace Botan + namespace Botan { class Modular_Reducer; @@ -10401,239 +9556,225 @@ class Modular_Reducer; class Montgomery_Params; /** -* The Montgomery representation of an integer -*/ -class BOTAN_UNSTABLE_API Montgomery_Int final - { + * The Montgomery representation of an integer + */ +class BOTAN_UNSTABLE_API Montgomery_Int final { public: - /** - * Create a zero-initialized Montgomery_Int - */ - Montgomery_Int(std::shared_ptr params) : m_params(params) {} + /** + * Create a zero-initialized Montgomery_Int + */ + Montgomery_Int(std::shared_ptr params) : m_params(params) {} - /** - * Create a Montgomery_Int - */ - Montgomery_Int(std::shared_ptr params, - const BigInt& v, - bool redc_needed = true); + /** + * Create a Montgomery_Int + */ + Montgomery_Int(std::shared_ptr params, const BigInt& v, + bool redc_needed = true); - /** - * Create a Montgomery_Int - */ - Montgomery_Int(std::shared_ptr params, - const uint8_t bits[], size_t len, - bool redc_needed = true); + /** + * Create a Montgomery_Int + */ + Montgomery_Int(std::shared_ptr params, const uint8_t bits[], + size_t len, bool redc_needed = true); - /** - * Create a Montgomery_Int - */ - Montgomery_Int(std::shared_ptr params, - const word words[], size_t len, - bool redc_needed = true); + /** + * Create a Montgomery_Int + */ + Montgomery_Int(std::shared_ptr params, const word words[], size_t len, + bool redc_needed = true); - bool operator==(const Montgomery_Int& other) const; - bool operator!=(const Montgomery_Int& other) const { return (m_v != other.m_v); } + bool operator==(const Montgomery_Int& other) const; + bool operator!=(const Montgomery_Int& other) const { return (m_v != other.m_v); } - std::vector serialize() const; + std::vector serialize() const; - size_t size() const; - bool is_one() const; - bool is_zero() const; + size_t size() const; + bool is_one() const; + bool is_zero() const; - void fix_size(); + void fix_size(); - /** - * Return the value to normal mod-p space - */ - BigInt value() const; + /** + * Return the value to normal mod-p space + */ + BigInt value() const; - /** - * Return the Montgomery representation - */ - const BigInt& repr() const { return m_v; } + /** + * Return the Montgomery representation + */ + const BigInt& repr() const { return m_v; } - Montgomery_Int operator+(const Montgomery_Int& other) const; + Montgomery_Int operator+(const Montgomery_Int& other) const; - Montgomery_Int operator-(const Montgomery_Int& other) const; + Montgomery_Int operator-(const Montgomery_Int& other) const; - Montgomery_Int& operator+=(const Montgomery_Int& other); + Montgomery_Int& operator+=(const Montgomery_Int& other); - Montgomery_Int& operator-=(const Montgomery_Int& other); + Montgomery_Int& operator-=(const Montgomery_Int& other); - Montgomery_Int operator*(const Montgomery_Int& other) const; + Montgomery_Int operator*(const Montgomery_Int& other) const; - Montgomery_Int& operator*=(const Montgomery_Int& other); + Montgomery_Int& operator*=(const Montgomery_Int& other); - Montgomery_Int& operator*=(const secure_vector& other); + Montgomery_Int& operator*=(const secure_vector& other); - Montgomery_Int& add(const Montgomery_Int& other, - secure_vector& ws); + Montgomery_Int& add(const Montgomery_Int& other, secure_vector& ws); - Montgomery_Int& sub(const Montgomery_Int& other, - secure_vector& ws); + Montgomery_Int& sub(const Montgomery_Int& other, secure_vector& ws); - Montgomery_Int mul(const Montgomery_Int& other, - secure_vector& ws) const; + Montgomery_Int mul(const Montgomery_Int& other, secure_vector& ws) const; - Montgomery_Int& mul_by(const Montgomery_Int& other, - secure_vector& ws); + Montgomery_Int& mul_by(const Montgomery_Int& other, secure_vector& ws); - Montgomery_Int& mul_by(const secure_vector& other, - secure_vector& ws); + Montgomery_Int& mul_by(const secure_vector& other, secure_vector& ws); - Montgomery_Int square(secure_vector& ws) const; + Montgomery_Int square(secure_vector& ws) const; - Montgomery_Int& square_this(secure_vector& ws); + Montgomery_Int& square_this(secure_vector& ws); - Montgomery_Int& square_this_n_times(secure_vector& ws, size_t n); + Montgomery_Int& square_this_n_times(secure_vector& ws, size_t n); - Montgomery_Int multiplicative_inverse() const; + Montgomery_Int multiplicative_inverse() const; - Montgomery_Int additive_inverse() const; + Montgomery_Int additive_inverse() const; - Montgomery_Int& mul_by_2(secure_vector& ws); + Montgomery_Int& mul_by_2(secure_vector& ws); - Montgomery_Int& mul_by_3(secure_vector& ws); + Montgomery_Int& mul_by_3(secure_vector& ws); - Montgomery_Int& mul_by_4(secure_vector& ws); + Montgomery_Int& mul_by_4(secure_vector& ws); - Montgomery_Int& mul_by_8(secure_vector& ws); + Montgomery_Int& mul_by_8(secure_vector& ws); - void const_time_poison() const { m_v.const_time_poison(); } - void const_time_unpoison() const { return m_v.const_time_unpoison(); } + void const_time_poison() const { m_v.const_time_poison(); } + void const_time_unpoison() const { return m_v.const_time_unpoison(); } private: - std::shared_ptr m_params; - BigInt m_v; - }; + std::shared_ptr m_params; + BigInt m_v; +}; /** -* Parameters for Montgomery Reduction -*/ -class BOTAN_UNSTABLE_API Montgomery_Params final - { + * Parameters for Montgomery Reduction + */ +class BOTAN_UNSTABLE_API Montgomery_Params final { public: - /** - * Initialize a set of Montgomery reduction parameters. These values - * can be shared by all values in a specific Montgomery domain. - */ - Montgomery_Params(const BigInt& p, const Modular_Reducer& mod_p); + /** + * Initialize a set of Montgomery reduction parameters. These values + * can be shared by all values in a specific Montgomery domain. + */ + Montgomery_Params(const BigInt& p, const Modular_Reducer& mod_p); - /** - * Initialize a set of Montgomery reduction parameters. These values - * can be shared by all values in a specific Montgomery domain. - */ - Montgomery_Params(const BigInt& p); + /** + * Initialize a set of Montgomery reduction parameters. These values + * can be shared by all values in a specific Montgomery domain. + */ + Montgomery_Params(const BigInt& p); - const BigInt& p() const { return m_p; } - const BigInt& R1() const { return m_r1; } - const BigInt& R2() const { return m_r2; } - const BigInt& R3() const { return m_r3; } + const BigInt& p() const { return m_p; } + const BigInt& R1() const { return m_r1; } + const BigInt& R2() const { return m_r2; } + const BigInt& R3() const { return m_r3; } - word p_dash() const { return m_p_dash; } + word p_dash() const { return m_p_dash; } - size_t p_words() const { return m_p_words; } + size_t p_words() const { return m_p_words; } - BigInt redc(const BigInt& x, - secure_vector& ws) const; + BigInt redc(const BigInt& x, secure_vector& ws) const; - BigInt mul(const BigInt& x, - const BigInt& y, - secure_vector& ws) const; + BigInt mul(const BigInt& x, const BigInt& y, secure_vector& ws) const; - BigInt mul(const BigInt& x, - const secure_vector& y, - secure_vector& ws) const; + BigInt mul(const BigInt& x, const secure_vector& y, secure_vector& ws) const; - void mul_by(BigInt& x, - const secure_vector& y, - secure_vector& ws) const; + void mul_by(BigInt& x, const secure_vector& y, secure_vector& ws) const; - void mul_by(BigInt& x, const BigInt& y, - secure_vector& ws) const; + void mul_by(BigInt& x, const BigInt& y, secure_vector& ws) const; - BigInt sqr(const BigInt& x, - secure_vector& ws) const; + BigInt sqr(const BigInt& x, secure_vector& ws) const; - void square_this(BigInt& x, - secure_vector& ws) const; + void square_this(BigInt& x, secure_vector& ws) const; - BigInt inv_mod_p(const BigInt& x) const; + BigInt inv_mod_p(const BigInt& x) const; private: - BigInt m_p; - BigInt m_r1; - BigInt m_r2; - BigInt m_r3; - word m_p_dash; - size_t m_p_words; - }; + BigInt m_p; + BigInt m_r1; + BigInt m_r2; + BigInt m_r3; + word m_p_dash; + size_t m_p_words; +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(mul128.h) +// BOTAN_FUTURE_INTERNAL_HEADER(mul128.h) namespace Botan { #if defined(__SIZEOF_INT128__) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT) - #define BOTAN_TARGET_HAS_NATIVE_UINT128 +#define BOTAN_TARGET_HAS_NATIVE_UINT128 - // Prefer TI mode over __int128 as GCC rejects the latter in pendantic mode - #if defined(__GNUG__) - typedef unsigned int uint128_t __attribute__((mode(TI))); - #else - typedef unsigned __int128 uint128_t; - #endif +// Prefer TI mode over __int128 as GCC rejects the latter in pendantic mode +#if defined(__GNUG__) +typedef unsigned int uint128_t __attribute__((mode(TI))); +#else +typedef unsigned __int128 uint128_t; +#endif #endif -} +} // namespace Botan #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128) -#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) \ - do { \ - const uint128_t r = static_cast(a) * b; \ - *hi = (r >> 64) & 0xFFFFFFFFFFFFFFFF; \ - *lo = (r ) & 0xFFFFFFFFFFFFFFFF; \ - } while(0) +#define BOTAN_FAST_64X64_MUL(a, b, lo, hi) \ + do { \ + const uint128_t r = static_cast(a) * b; \ + *hi = (r >> 64) & 0xFFFFFFFFFFFFFFFF; \ + *lo = (r) & 0xFFFFFFFFFFFFFFFF; \ + } while (0) #elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT) #include #pragma intrinsic(_umul128) -#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) \ - do { *lo = _umul128(a, b, hi); } while(0) +#define BOTAN_FAST_64X64_MUL(a, b, lo, hi) \ + do { \ + *lo = _umul128(a, b, hi); \ + } while (0) #elif defined(BOTAN_USE_GCC_INLINE_ASM) #if defined(BOTAN_TARGET_ARCH_IS_X86_64) -#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) do { \ - asm("mulq %3" : "=d" (*hi), "=a" (*lo) : "a" (a), "rm" (b) : "cc"); \ - } while(0) +#define BOTAN_FAST_64X64_MUL(a, b, lo, hi) \ + do { \ + asm("mulq %3" : "=d"(*hi), "=a"(*lo) : "a"(a), "rm"(b) : "cc"); \ + } while (0) #elif defined(BOTAN_TARGET_ARCH_IS_ALPHA) -#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) do { \ - asm("umulh %1,%2,%0" : "=r" (*hi) : "r" (a), "r" (b)); \ - *lo = a * b; \ -} while(0) +#define BOTAN_FAST_64X64_MUL(a, b, lo, hi) \ + do { \ + asm("umulh %1,%2,%0" : "=r"(*hi) : "r"(a), "r"(b)); \ + *lo = a * b; \ + } while (0) #elif defined(BOTAN_TARGET_ARCH_IS_IA64) -#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) do { \ - asm("xmpy.hu %0=%1,%2" : "=f" (*hi) : "f" (a), "f" (b)); \ - *lo = a * b; \ -} while(0) +#define BOTAN_FAST_64X64_MUL(a, b, lo, hi) \ + do { \ + asm("xmpy.hu %0=%1,%2" : "=f"(*hi) : "f"(a), "f"(b)); \ + *lo = a * b; \ + } while (0) #elif defined(BOTAN_TARGET_ARCH_IS_PPC64) -#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) do { \ - asm("mulhdu %0,%1,%2" : "=r" (*hi) : "r" (a), "r" (b) : "cc"); \ - *lo = a * b; \ -} while(0) +#define BOTAN_FAST_64X64_MUL(a, b, lo, hi) \ + do { \ + asm("mulhdu %0,%1,%2" : "=r"(*hi) : "r"(a), "r"(b) : "cc"); \ + *lo = a * b; \ + } while (0) #endif @@ -10642,57 +9783,56 @@ namespace Botan { namespace Botan { /** -* Perform a 64x64->128 bit multiplication -*/ -inline void mul64x64_128(uint64_t a, uint64_t b, uint64_t* lo, uint64_t* hi) - { + * Perform a 64x64->128 bit multiplication + */ +inline void mul64x64_128(uint64_t a, uint64_t b, uint64_t* lo, uint64_t* hi) { #if defined(BOTAN_FAST_64X64_MUL) - BOTAN_FAST_64X64_MUL(a, b, lo, hi); + BOTAN_FAST_64X64_MUL(a, b, lo, hi); #else - /* - * Do a 64x64->128 multiply using four 32x32->64 multiplies plus - * some adds and shifts. Last resort for CPUs like UltraSPARC (with - * 64-bit registers/ALU, but no 64x64->128 multiply) or 32-bit CPUs. - */ - const size_t HWORD_BITS = 32; - const uint32_t HWORD_MASK = 0xFFFFFFFF; + /* + * Do a 64x64->128 multiply using four 32x32->64 multiplies plus + * some adds and shifts. Last resort for CPUs like UltraSPARC (with + * 64-bit registers/ALU, but no 64x64->128 multiply) or 32-bit CPUs. + */ + const size_t HWORD_BITS = 32; + const uint32_t HWORD_MASK = 0xFFFFFFFF; - const uint32_t a_hi = (a >> HWORD_BITS); - const uint32_t a_lo = (a & HWORD_MASK); - const uint32_t b_hi = (b >> HWORD_BITS); - const uint32_t b_lo = (b & HWORD_MASK); + const uint32_t a_hi = (a >> HWORD_BITS); + const uint32_t a_lo = (a & HWORD_MASK); + const uint32_t b_hi = (b >> HWORD_BITS); + const uint32_t b_lo = (b & HWORD_MASK); - uint64_t x0 = static_cast(a_hi) * b_hi; - uint64_t x1 = static_cast(a_lo) * b_hi; - uint64_t x2 = static_cast(a_hi) * b_lo; - uint64_t x3 = static_cast(a_lo) * b_lo; + uint64_t x0 = static_cast(a_hi) * b_hi; + uint64_t x1 = static_cast(a_lo) * b_hi; + uint64_t x2 = static_cast(a_hi) * b_lo; + uint64_t x3 = static_cast(a_lo) * b_lo; - // this cannot overflow as (2^32-1)^2 + 2^32-1 < 2^64-1 - x2 += x3 >> HWORD_BITS; + // this cannot overflow as (2^32-1)^2 + 2^32-1 < 2^64-1 + x2 += x3 >> HWORD_BITS; - // this one can overflow - x2 += x1; + // this one can overflow + x2 += x1; - // propagate the carry if any - x0 += static_cast(static_cast(x2 < x1)) << HWORD_BITS; + // propagate the carry if any + x0 += static_cast(static_cast(x2 < x1)) << HWORD_BITS; - *hi = x0 + (x2 >> HWORD_BITS); - *lo = ((x2 & HWORD_MASK) << HWORD_BITS) + (x3 & HWORD_MASK); + *hi = x0 + (x2 >> HWORD_BITS); + *lo = ((x2 & HWORD_MASK) << HWORD_BITS) + (x3 & HWORD_MASK); #endif - } - } +} // namespace Botan + namespace Botan { namespace OIDS { /** -* Register an OID to string mapping. -* @param oid the oid to register -* @param name the name to be associated with the oid -*/ + * Register an OID to string mapping. + * @param oid the oid to register + * @param name the name to be associated with the oid + */ BOTAN_UNSTABLE_API void add_oid(const OID& oid, const std::string& name); BOTAN_UNSTABLE_API void add_oid2str(const OID& oid, const std::string& name); @@ -10704,708 +9844,644 @@ std::unordered_map load_oid2str_map(); std::unordered_map load_str2oid_map(); /** -* Resolve an OID -* @param oid the OID to look up -* @return name associated with this OID, or an empty string -*/ + * Resolve an OID + * @param oid the OID to look up + * @return name associated with this OID, or an empty string + */ BOTAN_UNSTABLE_API std::string oid2str_or_empty(const OID& oid); /** -* Find the OID to a name. The lookup will be performed in the -* general OID section of the configuration. -* @param name the name to resolve -* @return OID associated with the specified name -*/ + * Find the OID to a name. The lookup will be performed in the + * general OID section of the configuration. + * @param name the name to resolve + * @return OID associated with the specified name + */ BOTAN_UNSTABLE_API OID str2oid_or_empty(const std::string& name); BOTAN_UNSTABLE_API std::string oid2str_or_throw(const OID& oid); /** -* See if an OID exists in the internal table. -* @param oid the oid to check for -* @return true if the oid is registered -*/ -BOTAN_UNSTABLE_API bool BOTAN_DEPRECATED("Just lookup the value instead") have_oid(const std::string& oid); + * See if an OID exists in the internal table. + * @param oid the oid to check for + * @return true if the oid is registered + */ +BOTAN_UNSTABLE_API bool BOTAN_DEPRECATED("Just lookup the value instead") + have_oid(const std::string& oid); /** -* Tests whether the specified OID stands for the specified name. -* @param oid the OID to check -* @param name the name to check -* @return true if the specified OID stands for the specified name -*/ -inline bool BOTAN_DEPRECATED("Use oid == OID::from_string(name)") name_of(const OID& oid, const std::string& name) - { - return (oid == str2oid_or_empty(name)); - } - -/** -* Prefer oid2str_or_empty -*/ -inline std::string lookup(const OID& oid) - { - return oid2str_or_empty(oid); - } - -/** -* Prefer str2oid_or_empty -*/ -inline OID lookup(const std::string& name) - { - return str2oid_or_empty(name); - } - -inline std::string BOTAN_DEPRECATED("Use oid2str_or_empty") oid2str(const OID& oid) - { - return oid2str_or_empty(oid); - } - -inline OID BOTAN_DEPRECATED("Use str2oid_or_empty") str2oid(const std::string& name) - { - return str2oid_or_empty(name); - } - + * Tests whether the specified OID stands for the specified name. + * @param oid the OID to check + * @param name the name to check + * @return true if the specified OID stands for the specified name + */ +inline bool BOTAN_DEPRECATED("Use oid == OID::from_string(name)") + name_of(const OID& oid, const std::string& name) { + return (oid == str2oid_or_empty(name)); } +/** + * Prefer oid2str_or_empty + */ +inline std::string lookup(const OID& oid) { return oid2str_or_empty(oid); } + +/** + * Prefer str2oid_or_empty + */ +inline OID lookup(const std::string& name) { return str2oid_or_empty(name); } + +inline std::string BOTAN_DEPRECATED("Use oid2str_or_empty") oid2str(const OID& oid) { + return oid2str_or_empty(oid); } +inline OID BOTAN_DEPRECATED("Use str2oid_or_empty") str2oid(const std::string& name) { + return str2oid_or_empty(name); +} -//BOTAN_FUTURE_INTERNAL_HEADER(parsing.h) +} // namespace OIDS + +} // namespace Botan + +// BOTAN_FUTURE_INTERNAL_HEADER(parsing.h) namespace Botan { /** -* Parse a SCAN-style algorithm name -* @param scan_name the name -* @return the name components -*/ -BOTAN_PUBLIC_API(2,0) std::vector -parse_algorithm_name(const std::string& scan_name); + * Parse a SCAN-style algorithm name + * @param scan_name the name + * @return the name components + */ +BOTAN_PUBLIC_API(2, 0) std::vector parse_algorithm_name(const std::string& scan_name); /** -* Split a string -* @param str the input string -* @param delim the delimitor -* @return string split by delim -*/ -BOTAN_PUBLIC_API(2,0) std::vector split_on( - const std::string& str, char delim); + * Split a string + * @param str the input string + * @param delim the delimitor + * @return string split by delim + */ +BOTAN_PUBLIC_API(2, 0) std::vector split_on(const std::string& str, char delim); /** -* Split a string on a character predicate -* @param str the input string -* @param pred the predicate -* -* This function will likely be removed in a future release -*/ -BOTAN_PUBLIC_API(2,0) std::vector -split_on_pred(const std::string& str, - std::function pred); + * Split a string on a character predicate + * @param str the input string + * @param pred the predicate + * + * This function will likely be removed in a future release + */ +BOTAN_PUBLIC_API(2, 0) +std::vector split_on_pred(const std::string& str, std::function pred); /** -* Erase characters from a string -*/ -BOTAN_PUBLIC_API(2,0) + * Erase characters from a string + */ +BOTAN_PUBLIC_API(2, 0) BOTAN_DEPRECATED("Unused") std::string erase_chars(const std::string& str, const std::set& chars); /** -* Replace a character in a string -* @param str the input string -* @param from_char the character to replace -* @param to_char the character to replace it with -* @return str with all instances of from_char replaced by to_char -*/ -BOTAN_PUBLIC_API(2,0) + * Replace a character in a string + * @param str the input string + * @param from_char the character to replace + * @param to_char the character to replace it with + * @return str with all instances of from_char replaced by to_char + */ +BOTAN_PUBLIC_API(2, 0) BOTAN_DEPRECATED("Unused") -std::string replace_char(const std::string& str, - char from_char, - char to_char); +std::string replace_char(const std::string& str, char from_char, char to_char); /** -* Replace a character in a string -* @param str the input string -* @param from_chars the characters to replace -* @param to_char the character to replace it with -* @return str with all instances of from_chars replaced by to_char -*/ -BOTAN_PUBLIC_API(2,0) + * Replace a character in a string + * @param str the input string + * @param from_chars the characters to replace + * @param to_char the character to replace it with + * @return str with all instances of from_chars replaced by to_char + */ +BOTAN_PUBLIC_API(2, 0) BOTAN_DEPRECATED("Unused") -std::string replace_chars(const std::string& str, - const std::set& from_chars, - char to_char); +std::string replace_chars(const std::string& str, const std::set& from_chars, char to_char); /** -* Join a string -* @param strs strings to join -* @param delim the delimitor -* @return string joined by delim -*/ -BOTAN_PUBLIC_API(2,0) -std::string string_join(const std::vector& strs, - char delim); + * Join a string + * @param strs strings to join + * @param delim the delimitor + * @return string joined by delim + */ +BOTAN_PUBLIC_API(2, 0) +std::string string_join(const std::vector& strs, char delim); /** -* Parse an ASN.1 OID -* @param oid the OID in string form -* @return OID components -*/ -BOTAN_PUBLIC_API(2,0) std::vector -BOTAN_DEPRECATED("Use OID::from_string(oid).get_components()") parse_asn1_oid(const std::string& oid); + * Parse an ASN.1 OID + * @param oid the OID in string form + * @return OID components + */ +BOTAN_PUBLIC_API(2, 0) +std::vector BOTAN_DEPRECATED("Use OID::from_string(oid).get_components()") + parse_asn1_oid(const std::string& oid); /** -* Compare two names using the X.509 comparison algorithm -* @param name1 the first name -* @param name2 the second name -* @return true if name1 is the same as name2 by the X.509 comparison rules -*/ -BOTAN_PUBLIC_API(2,0) -bool x500_name_cmp(const std::string& name1, - const std::string& name2); + * Compare two names using the X.509 comparison algorithm + * @param name1 the first name + * @param name2 the second name + * @return true if name1 is the same as name2 by the X.509 comparison rules + */ +BOTAN_PUBLIC_API(2, 0) +bool x500_name_cmp(const std::string& name1, const std::string& name2); /** -* Convert a string to a number -* @param str the string to convert -* @return number value of the string -*/ -BOTAN_PUBLIC_API(2,0) uint32_t to_u32bit(const std::string& str); + * Convert a string to a number + * @param str the string to convert + * @return number value of the string + */ +BOTAN_PUBLIC_API(2, 0) uint32_t to_u32bit(const std::string& str); /** -* Convert a string to a number -* @param str the string to convert -* @return number value of the string -*/ -BOTAN_PUBLIC_API(2,3) uint16_t to_uint16(const std::string& str); + * Convert a string to a number + * @param str the string to convert + * @return number value of the string + */ +BOTAN_PUBLIC_API(2, 3) uint16_t to_uint16(const std::string& str); /** -* Convert a time specification to a number -* @param timespec the time specification -* @return number of seconds represented by timespec -*/ -BOTAN_PUBLIC_API(2,0) uint32_t BOTAN_DEPRECATED("Not used anymore") -timespec_to_u32bit(const std::string& timespec); + * Convert a time specification to a number + * @param timespec the time specification + * @return number of seconds represented by timespec + */ +BOTAN_PUBLIC_API(2, 0) +uint32_t BOTAN_DEPRECATED("Not used anymore") timespec_to_u32bit(const std::string& timespec); /** -* Convert a string representation of an IPv4 address to a number -* @param ip_str the string representation -* @return integer IPv4 address -*/ -BOTAN_PUBLIC_API(2,0) uint32_t string_to_ipv4(const std::string& ip_str); + * Convert a string representation of an IPv4 address to a number + * @param ip_str the string representation + * @return integer IPv4 address + */ +BOTAN_PUBLIC_API(2, 0) uint32_t string_to_ipv4(const std::string& ip_str); /** -* Convert an IPv4 address to a string -* @param ip_addr the IPv4 address to convert -* @return string representation of the IPv4 address -*/ -BOTAN_PUBLIC_API(2,0) std::string ipv4_to_string(uint32_t ip_addr); + * Convert an IPv4 address to a string + * @param ip_addr the IPv4 address to convert + * @return string representation of the IPv4 address + */ +BOTAN_PUBLIC_API(2, 0) std::string ipv4_to_string(uint32_t ip_addr); -std::map BOTAN_PUBLIC_API(2,0) read_cfg(std::istream& is); +std::map BOTAN_PUBLIC_API(2, 0) read_cfg(std::istream& is); /** -* Accepts key value pairs deliminated by commas: -* -* "" (returns empty map) -* "K=V" (returns map {'K': 'V'}) -* "K1=V1,K2=V2" -* "K1=V1,K2=V2,K3=V3" -* "K1=V1,K2=V2,K3=a_value\,with\,commas_and_\=equals" -* -* Values may be empty, keys must be non-empty and unique. Duplicate -* keys cause an exception. -* -* Within both key and value, comma and equals can be escaped with -* backslash. Backslash can also be escaped. -*/ -std::map BOTAN_PUBLIC_API(2,8) read_kv(const std::string& kv); + * Accepts key value pairs deliminated by commas: + * + * "" (returns empty map) + * "K=V" (returns map {'K': 'V'}) + * "K1=V1,K2=V2" + * "K1=V1,K2=V2,K3=V3" + * "K1=V1,K2=V2,K3=a_value\,with\,commas_and_\=equals" + * + * Values may be empty, keys must be non-empty and unique. Duplicate + * keys cause an exception. + * + * Within both key and value, comma and equals can be escaped with + * backslash. Backslash can also be escaped. + */ +std::map BOTAN_PUBLIC_API(2, 8) read_kv(const std::string& kv); -std::string BOTAN_PUBLIC_API(2,0) clean_ws(const std::string& s); +std::string BOTAN_PUBLIC_API(2, 0) clean_ws(const std::string& s); /** -* Check if the given hostname is a match for the specified wildcard -*/ -bool BOTAN_PUBLIC_API(2,0) host_wildcard_match(const std::string& wildcard, - const std::string& host); + * Check if the given hostname is a match for the specified wildcard + */ +bool BOTAN_PUBLIC_API(2, 0) + host_wildcard_match(const std::string& wildcard, const std::string& host); - -} +} // namespace Botan namespace Botan { /** -* Base class for PBKDF (password based key derivation function) -* implementations. Converts a password into a key using a salt -* and iterated hashing to make brute force attacks harder. -* -* Starting in 2.8 this functionality is also offered by PasswordHash. -* The PBKDF interface may be removed in a future release. -*/ -class BOTAN_PUBLIC_API(2,0) PBKDF - { + * Base class for PBKDF (password based key derivation function) + * implementations. Converts a password into a key using a salt + * and iterated hashing to make brute force attacks harder. + * + * Starting in 2.8 this functionality is also offered by PasswordHash. + * The PBKDF interface may be removed in a future release. + */ +class BOTAN_PUBLIC_API(2, 0) PBKDF { public: - /** - * Create an instance based on a name - * If provider is empty then best available is chosen. - * @param algo_spec algorithm name - * @param provider provider implementation to choose - * @return a null pointer if the algo/provider combination cannot be found - */ - static std::unique_ptr create(const std::string& algo_spec, - const std::string& provider = ""); + /** + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to choose + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr create(const std::string& algo_spec, + const std::string& provider = ""); - /** - * Create an instance based on a name, or throw if the - * algo/provider combination cannot be found. If provider is - * empty then best available is chosen. - */ - static std::unique_ptr - create_or_throw(const std::string& algo_spec, - const std::string& provider = ""); + /** + * Create an instance based on a name, or throw if the + * algo/provider combination cannot be found. If provider is + * empty then best available is chosen. + */ + static std::unique_ptr create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); - /** - * @return list of available providers for this algorithm, empty if not available - */ - static std::vector providers(const std::string& algo_spec); + /** + * @return list of available providers for this algorithm, empty if not available + */ + static std::vector providers(const std::string& algo_spec); - /** - * @return new instance of this same algorithm - */ - virtual PBKDF* clone() const = 0; + /** + * @return new instance of this same algorithm + */ + virtual PBKDF* clone() const = 0; - /** - * @return name of this PBKDF - */ - virtual std::string name() const = 0; + /** + * @return name of this PBKDF + */ + virtual std::string name() const = 0; - virtual ~PBKDF() = default; + virtual ~PBKDF() = default; - /** - * Derive a key from a passphrase for a number of iterations - * specified by either iterations or if iterations == 0 then - * running until msec time has elapsed. - * - * @param out buffer to store the derived key, must be of out_len bytes - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param iterations the number of iterations to use (use 10K or more) - * @param msec if iterations is zero, then instead the PBKDF is - * run until msec milliseconds has passed. - * @return the number of iterations performed - */ - virtual size_t pbkdf(uint8_t out[], size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - size_t iterations, - std::chrono::milliseconds msec) const = 0; + /** + * Derive a key from a passphrase for a number of iterations + * specified by either iterations or if iterations == 0 then + * running until msec time has elapsed. + * + * @param out buffer to store the derived key, must be of out_len bytes + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param iterations the number of iterations to use (use 10K or more) + * @param msec if iterations is zero, then instead the PBKDF is + * run until msec milliseconds has passed. + * @return the number of iterations performed + */ + virtual size_t pbkdf(uint8_t out[], size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, size_t iterations, + std::chrono::milliseconds msec) const = 0; - /** - * Derive a key from a passphrase for a number of iterations. - * - * @param out buffer to store the derived key, must be of out_len bytes - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param iterations the number of iterations to use (use 10K or more) - */ - void pbkdf_iterations(uint8_t out[], size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - size_t iterations) const; + /** + * Derive a key from a passphrase for a number of iterations. + * + * @param out buffer to store the derived key, must be of out_len bytes + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param iterations the number of iterations to use (use 10K or more) + */ + void pbkdf_iterations(uint8_t out[], size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, size_t iterations) const; - /** - * Derive a key from a passphrase, running until msec time has elapsed. - * - * @param out buffer to store the derived key, must be of out_len bytes - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param msec if iterations is zero, then instead the PBKDF is - * run until msec milliseconds has passed. - * @param iterations set to the number iterations executed - */ - void pbkdf_timed(uint8_t out[], size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - std::chrono::milliseconds msec, - size_t& iterations) const; + /** + * Derive a key from a passphrase, running until msec time has elapsed. + * + * @param out buffer to store the derived key, must be of out_len bytes + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param msec if iterations is zero, then instead the PBKDF is + * run until msec milliseconds has passed. + * @param iterations set to the number iterations executed + */ + void pbkdf_timed(uint8_t out[], size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, std::chrono::milliseconds msec, + size_t& iterations) const; - /** - * Derive a key from a passphrase for a number of iterations. - * - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param iterations the number of iterations to use (use 10K or more) - * @return the derived key - */ - secure_vector pbkdf_iterations(size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - size_t iterations) const; + /** + * Derive a key from a passphrase for a number of iterations. + * + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param iterations the number of iterations to use (use 10K or more) + * @return the derived key + */ + secure_vector pbkdf_iterations(size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations) const; - /** - * Derive a key from a passphrase, running until msec time has elapsed. - * - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param msec if iterations is zero, then instead the PBKDF is - * run until msec milliseconds has passed. - * @param iterations set to the number iterations executed - * @return the derived key - */ - secure_vector pbkdf_timed(size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - std::chrono::milliseconds msec, - size_t& iterations) const; + /** + * Derive a key from a passphrase, running until msec time has elapsed. + * + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param msec if iterations is zero, then instead the PBKDF is + * run until msec milliseconds has passed. + * @param iterations set to the number iterations executed + * @return the derived key + */ + secure_vector pbkdf_timed(size_t out_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + std::chrono::milliseconds msec, size_t& iterations) const; - // Following kept for compat with 1.10: + // Following kept for compat with 1.10: - /** - * Derive a key from a passphrase - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param iterations the number of iterations to use (use 10K or more) - */ - OctetString derive_key(size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - size_t iterations) const - { - return pbkdf_iterations(out_len, passphrase, salt, salt_len, iterations); - } + /** + * Derive a key from a passphrase + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param iterations the number of iterations to use (use 10K or more) + */ + OctetString derive_key(size_t out_len, const std::string& passphrase, const uint8_t salt[], + size_t salt_len, size_t iterations) const { + return pbkdf_iterations(out_len, passphrase, salt, salt_len, iterations); + } - /** - * Derive a key from a passphrase - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param iterations the number of iterations to use (use 10K or more) - */ - template - OctetString derive_key(size_t out_len, - const std::string& passphrase, - const std::vector& salt, - size_t iterations) const - { - return pbkdf_iterations(out_len, passphrase, salt.data(), salt.size(), iterations); - } + /** + * Derive a key from a passphrase + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param iterations the number of iterations to use (use 10K or more) + */ + template + OctetString derive_key(size_t out_len, const std::string& passphrase, + const std::vector& salt, size_t iterations) const { + return pbkdf_iterations(out_len, passphrase, salt.data(), salt.size(), iterations); + } - /** - * Derive a key from a passphrase - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param msec is how long to run the PBKDF - * @param iterations is set to the number of iterations used - */ - OctetString derive_key(size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - std::chrono::milliseconds msec, - size_t& iterations) const - { - return pbkdf_timed(out_len, passphrase, salt, salt_len, msec, iterations); - } + /** + * Derive a key from a passphrase + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param msec is how long to run the PBKDF + * @param iterations is set to the number of iterations used + */ + OctetString derive_key(size_t out_len, const std::string& passphrase, const uint8_t salt[], + size_t salt_len, std::chrono::milliseconds msec, + size_t& iterations) const { + return pbkdf_timed(out_len, passphrase, salt, salt_len, msec, iterations); + } - /** - * Derive a key from a passphrase using a certain amount of time - * @param out_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param msec is how long to run the PBKDF - * @param iterations is set to the number of iterations used - */ - template - OctetString derive_key(size_t out_len, - const std::string& passphrase, - const std::vector& salt, - std::chrono::milliseconds msec, - size_t& iterations) const - { - return pbkdf_timed(out_len, passphrase, salt.data(), salt.size(), msec, iterations); - } - }; + /** + * Derive a key from a passphrase using a certain amount of time + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param msec is how long to run the PBKDF + * @param iterations is set to the number of iterations used + */ + template + OctetString derive_key(size_t out_len, const std::string& passphrase, + const std::vector& salt, std::chrono::milliseconds msec, + size_t& iterations) const { + return pbkdf_timed(out_len, passphrase, salt.data(), salt.size(), msec, iterations); + } +}; /* -* Compatibility typedef -*/ + * Compatibility typedef + */ typedef PBKDF S2K; /** -* Password based key derivation function factory method -* @param algo_spec the name of the desired PBKDF algorithm -* @param provider the provider to use -* @return pointer to newly allocated object of that type -*/ -inline PBKDF* get_pbkdf(const std::string& algo_spec, - const std::string& provider = "") - { - return PBKDF::create_or_throw(algo_spec, provider).release(); - } - -inline PBKDF* get_s2k(const std::string& algo_spec) - { - return get_pbkdf(algo_spec); - } - - + * Password based key derivation function factory method + * @param algo_spec the name of the desired PBKDF algorithm + * @param provider the provider to use + * @return pointer to newly allocated object of that type + */ +inline PBKDF* get_pbkdf(const std::string& algo_spec, const std::string& provider = "") { + return PBKDF::create_or_throw(algo_spec, provider).release(); } +inline PBKDF* get_s2k(const std::string& algo_spec) { return get_pbkdf(algo_spec); } + +} // namespace Botan + namespace Botan { /** -* Base class for password based key derivation functions. -* -* Converts a password into a key using a salt and iterated hashing to -* make brute force attacks harder. -*/ -class BOTAN_PUBLIC_API(2,8) PasswordHash - { + * Base class for password based key derivation functions. + * + * Converts a password into a key using a salt and iterated hashing to + * make brute force attacks harder. + */ +class BOTAN_PUBLIC_API(2, 8) PasswordHash { public: - virtual ~PasswordHash() = default; + virtual ~PasswordHash() = default; - virtual std::string to_string() const = 0; + virtual std::string to_string() const = 0; - /** - * Most password hashes have some notion of iterations. - */ - virtual size_t iterations() const = 0; + /** + * Most password hashes have some notion of iterations. + */ + virtual size_t iterations() const = 0; - /** - * Some password hashing algorithms have a parameter which controls how - * much memory is used. If not supported by some algorithm, returns 0. - */ - virtual size_t memory_param() const { return 0; } + /** + * Some password hashing algorithms have a parameter which controls how + * much memory is used. If not supported by some algorithm, returns 0. + */ + virtual size_t memory_param() const { return 0; } - /** - * Some password hashing algorithms have a parallelism parameter. - * If the algorithm does not support this notion, then the - * function returns zero. This allows distinguishing between a - * password hash which just does not support parallel operation, - * vs one that does support parallel operation but which has been - * configured to use a single lane. - */ - virtual size_t parallelism() const { return 0; } + /** + * Some password hashing algorithms have a parallelism parameter. + * If the algorithm does not support this notion, then the + * function returns zero. This allows distinguishing between a + * password hash which just does not support parallel operation, + * vs one that does support parallel operation but which has been + * configured to use a single lane. + */ + virtual size_t parallelism() const { return 0; } - /** - * Returns an estimate of the total memory usage required to perform this - * key derivation. - * - * If this algorithm uses a small and constant amount of memory, with no - * effort made towards being memory hard, this function returns 0. - */ - virtual size_t total_memory_usage() const { return 0; } + /** + * Returns an estimate of the total memory usage required to perform this + * key derivation. + * + * If this algorithm uses a small and constant amount of memory, with no + * effort made towards being memory hard, this function returns 0. + */ + virtual size_t total_memory_usage() const { return 0; } - /** - * Derive a key from a password - * - * @param out buffer to store the derived key, must be of out_len bytes - * @param out_len the desired length of the key to produce - * @param password the password to derive the key from - * @param password_len the length of password in bytes - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * - * This function is const, but is not thread safe. Different threads should - * either use unique objects, or serialize all access. - */ - virtual void derive_key(uint8_t out[], size_t out_len, - const char* password, size_t password_len, - const uint8_t salt[], size_t salt_len) const = 0; - }; + /** + * Derive a key from a password + * + * @param out buffer to store the derived key, must be of out_len bytes + * @param out_len the desired length of the key to produce + * @param password the password to derive the key from + * @param password_len the length of password in bytes + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * + * This function is const, but is not thread safe. Different threads should + * either use unique objects, or serialize all access. + */ + virtual void derive_key(uint8_t out[], size_t out_len, const char* password, + size_t password_len, const uint8_t salt[], size_t salt_len) const = 0; +}; -class BOTAN_PUBLIC_API(2,8) PasswordHashFamily - { +class BOTAN_PUBLIC_API(2, 8) PasswordHashFamily { public: - /** - * Create an instance based on a name - * If provider is empty then best available is chosen. - * @param algo_spec algorithm name - * @param provider provider implementation to choose - * @return a null pointer if the algo/provider combination cannot be found - */ - static std::unique_ptr create(const std::string& algo_spec, - const std::string& provider = ""); + /** + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to choose + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr create(const std::string& algo_spec, + const std::string& provider = ""); - /** - * Create an instance based on a name, or throw if the - * algo/provider combination cannot be found. If provider is - * empty then best available is chosen. - */ - static std::unique_ptr - create_or_throw(const std::string& algo_spec, - const std::string& provider = ""); + /** + * Create an instance based on a name, or throw if the + * algo/provider combination cannot be found. If provider is + * empty then best available is chosen. + */ + static std::unique_ptr create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); - /** - * @return list of available providers for this algorithm, empty if not available - */ - static std::vector providers(const std::string& algo_spec); + /** + * @return list of available providers for this algorithm, empty if not available + */ + static std::vector providers(const std::string& algo_spec); - virtual ~PasswordHashFamily() = default; + virtual ~PasswordHashFamily() = default; - /** - * @return name of this PasswordHash - */ - virtual std::string name() const = 0; + /** + * @return name of this PasswordHash + */ + virtual std::string name() const = 0; - /** - * Return a new parameter set tuned for this machine - * @param output_length how long the output length will be - * @param msec the desired execution time in milliseconds - * - * @param max_memory_usage_mb some password hash functions can use a tunable - * amount of memory, in this case max_memory_usage limits the amount of RAM - * the returned parameters will require, in mebibytes (2**20 bytes). It may - * require some small amount above the request. Set to zero to place no - * limit at all. - */ - virtual std::unique_ptr tune(size_t output_length, - std::chrono::milliseconds msec, - size_t max_memory_usage_mb = 0) const = 0; + /** + * Return a new parameter set tuned for this machine + * @param output_length how long the output length will be + * @param msec the desired execution time in milliseconds + * + * @param max_memory_usage_mb some password hash functions can use a tunable + * amount of memory, in this case max_memory_usage limits the amount of RAM + * the returned parameters will require, in mebibytes (2**20 bytes). It may + * require some small amount above the request. Set to zero to place no + * limit at all. + */ + virtual std::unique_ptr tune(size_t output_length, std::chrono::milliseconds msec, + size_t max_memory_usage_mb = 0) const = 0; - /** - * Return some default parameter set for this PBKDF that should be good - * enough for most users. The value returned may change over time as - * processing power and attacks improve. - */ - virtual std::unique_ptr default_params() const = 0; + /** + * Return some default parameter set for this PBKDF that should be good + * enough for most users. The value returned may change over time as + * processing power and attacks improve. + */ + virtual std::unique_ptr default_params() const = 0; - /** - * Return a parameter chosen based on a rough approximation with the - * specified iteration count. The exact value this returns for a particular - * algorithm may change from over time. Think of it as an alternative to - * tune, where time is expressed in terms of PBKDF2 iterations rather than - * milliseconds. - */ - virtual std::unique_ptr from_iterations(size_t iterations) const = 0; + /** + * Return a parameter chosen based on a rough approximation with the + * specified iteration count. The exact value this returns for a particular + * algorithm may change from over time. Think of it as an alternative to + * tune, where time is expressed in terms of PBKDF2 iterations rather than + * milliseconds. + */ + virtual std::unique_ptr from_iterations(size_t iterations) const = 0; - /** - * Create a password hash using some scheme specific format. - * Eg PBKDF2 and PGP-S2K set iterations in i1 - * Scrypt uses N,r,p in i{1-3} - * Bcrypt-PBKDF just has iterations - * Argon2{i,d,id} would use iterations, memory, parallelism for i{1-3}, - * and Argon2 type is part of the family. - * - * Values not needed should be set to 0 - */ - virtual std::unique_ptr from_params( - size_t i1, - size_t i2 = 0, - size_t i3 = 0) const = 0; - }; + /** + * Create a password hash using some scheme specific format. + * Eg PBKDF2 and PGP-S2K set iterations in i1 + * Scrypt uses N,r,p in i{1-3} + * Bcrypt-PBKDF just has iterations + * Argon2{i,d,id} would use iterations, memory, parallelism for i{1-3}, + * and Argon2 type is part of the family. + * + * Values not needed should be set to 0 + */ + virtual std::unique_ptr from_params(size_t i1, size_t i2 = 0, + size_t i3 = 0) const = 0; +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(pbkdf2.h) +// BOTAN_FUTURE_INTERNAL_HEADER(pbkdf2.h) namespace Botan { -BOTAN_PUBLIC_API(2,0) size_t pbkdf2(MessageAuthenticationCode& prf, - uint8_t out[], - size_t out_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - size_t iterations, - std::chrono::milliseconds msec); +BOTAN_PUBLIC_API(2, 0) +size_t pbkdf2(MessageAuthenticationCode& prf, uint8_t out[], size_t out_len, + const std::string& passphrase, const uint8_t salt[], size_t salt_len, + size_t iterations, std::chrono::milliseconds msec); /** -* Perform PBKDF2. The prf is assumed to be keyed already. -*/ -BOTAN_PUBLIC_API(2,8) void pbkdf2(MessageAuthenticationCode& prf, - uint8_t out[], size_t out_len, - const uint8_t salt[], size_t salt_len, - size_t iterations); + * Perform PBKDF2. The prf is assumed to be keyed already. + */ +BOTAN_PUBLIC_API(2, 8) +void pbkdf2(MessageAuthenticationCode& prf, uint8_t out[], size_t out_len, const uint8_t salt[], + size_t salt_len, size_t iterations); /** -* PBKDF2 -*/ -class BOTAN_PUBLIC_API(2,8) PBKDF2 final : public PasswordHash - { + * PBKDF2 + */ +class BOTAN_PUBLIC_API(2, 8) PBKDF2 final : public PasswordHash { public: - PBKDF2(const MessageAuthenticationCode& prf, size_t iter) : - m_prf(prf.clone()), - m_iterations(iter) - {} + PBKDF2(const MessageAuthenticationCode& prf, size_t iter) + : m_prf(prf.clone()), m_iterations(iter) {} - PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec); + PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec); - size_t iterations() const override { return m_iterations; } + size_t iterations() const override { return m_iterations; } - std::string to_string() const override; + std::string to_string() const override; + + void derive_key(uint8_t out[], size_t out_len, const char* password, size_t password_len, + const uint8_t salt[], size_t salt_len) const override; - void derive_key(uint8_t out[], size_t out_len, - const char* password, size_t password_len, - const uint8_t salt[], size_t salt_len) const override; private: - std::unique_ptr m_prf; - size_t m_iterations; - }; + std::unique_ptr m_prf; + size_t m_iterations; +}; /** -* Family of PKCS #5 PBKDF2 operations -*/ -class BOTAN_PUBLIC_API(2,8) PBKDF2_Family final : public PasswordHashFamily - { + * Family of PKCS #5 PBKDF2 operations + */ +class BOTAN_PUBLIC_API(2, 8) PBKDF2_Family final : public PasswordHashFamily { public: - PBKDF2_Family(MessageAuthenticationCode* prf) : m_prf(prf) {} + PBKDF2_Family(MessageAuthenticationCode* prf) : m_prf(prf) {} - std::string name() const override; + std::string name() const override; - std::unique_ptr tune(size_t output_len, - std::chrono::milliseconds msec, - size_t max_memory) const override; + std::unique_ptr tune(size_t output_len, std::chrono::milliseconds msec, + size_t max_memory) const override; - /** - * Return some default parameter set for this PBKDF that should be good - * enough for most users. The value returned may change over time as - * processing power and attacks improve. - */ - std::unique_ptr default_params() const override; + /** + * Return some default parameter set for this PBKDF that should be good + * enough for most users. The value returned may change over time as + * processing power and attacks improve. + */ + std::unique_ptr default_params() const override; - std::unique_ptr from_iterations(size_t iter) const override; + std::unique_ptr from_iterations(size_t iter) const override; + + std::unique_ptr from_params(size_t iter, size_t, size_t) const override; - std::unique_ptr from_params( - size_t iter, size_t, size_t) const override; private: - std::unique_ptr m_prf; - }; + std::unique_ptr m_prf; +}; /** -* PKCS #5 PBKDF2 (old interface) -*/ -class BOTAN_PUBLIC_API(2,0) PKCS5_PBKDF2 final : public PBKDF - { + * PKCS #5 PBKDF2 (old interface) + */ +class BOTAN_PUBLIC_API(2, 0) PKCS5_PBKDF2 final : public PBKDF { public: - std::string name() const override; + std::string name() const override; - PBKDF* clone() const override; + PBKDF* clone() const override; - size_t pbkdf(uint8_t output_buf[], size_t output_len, - const std::string& passphrase, - const uint8_t salt[], size_t salt_len, - size_t iterations, - std::chrono::milliseconds msec) const override; + size_t pbkdf(uint8_t output_buf[], size_t output_len, const std::string& passphrase, + const uint8_t salt[], size_t salt_len, size_t iterations, + std::chrono::milliseconds msec) const override; + + /** + * Create a PKCS #5 instance using the specified message auth code + * @param mac_fn the MAC object to use as PRF + */ + explicit PKCS5_PBKDF2(MessageAuthenticationCode* mac_fn) : m_mac(mac_fn) {} - /** - * Create a PKCS #5 instance using the specified message auth code - * @param mac_fn the MAC object to use as PRF - */ - explicit PKCS5_PBKDF2(MessageAuthenticationCode* mac_fn) : m_mac(mac_fn) {} private: - std::unique_ptr m_mac; - }; + std::unique_ptr m_mac; +}; -} +} // namespace Botan namespace Botan { @@ -11414,75 +10490,67 @@ class DataSource; namespace PEM_Code { /** -* Encode some binary data in PEM format -* @param data binary data to encode -* @param data_len length of binary data in bytes -* @param label PEM label put after BEGIN and END -* @param line_width after this many characters, a new line is inserted -*/ -BOTAN_PUBLIC_API(2,0) std::string encode(const uint8_t data[], - size_t data_len, - const std::string& label, - size_t line_width = 64); + * Encode some binary data in PEM format + * @param data binary data to encode + * @param data_len length of binary data in bytes + * @param label PEM label put after BEGIN and END + * @param line_width after this many characters, a new line is inserted + */ +BOTAN_PUBLIC_API(2, 0) +std::string encode(const uint8_t data[], size_t data_len, const std::string& label, + size_t line_width = 64); /** -* Encode some binary data in PEM format -* @param data binary data to encode -* @param label PEM label -* @param line_width after this many characters, a new line is inserted -*/ -template -std::string encode(const std::vector& data, - const std::string& label, - size_t line_width = 64) - { - return encode(data.data(), data.size(), label, line_width); - } - -/** -* Decode PEM data -* @param pem a datasource containing PEM encoded data -* @param label is set to the PEM label found for later inspection -*/ -BOTAN_PUBLIC_API(2,0) secure_vector decode(DataSource& pem, - std::string& label); - -/** -* Decode PEM data -* @param pem a string containing PEM encoded data -* @param label is set to the PEM label found for later inspection -*/ -BOTAN_PUBLIC_API(2,0) secure_vector decode(const std::string& pem, - std::string& label); - -/** -* Decode PEM data -* @param pem a datasource containing PEM encoded data -* @param label is what we expect the label to be -*/ -BOTAN_PUBLIC_API(2,0) -secure_vector decode_check_label(DataSource& pem, - const std::string& label); - -/** -* Decode PEM data -* @param pem a string containing PEM encoded data -* @param label is what we expect the label to be -*/ -BOTAN_PUBLIC_API(2,0) -secure_vector decode_check_label(const std::string& pem, - const std::string& label); - -/** -* Heuristic test for PEM data. -*/ -BOTAN_PUBLIC_API(2,0) bool matches(DataSource& source, - const std::string& extra = "", - size_t search_range = 4096); - + * Encode some binary data in PEM format + * @param data binary data to encode + * @param label PEM label + * @param line_width after this many characters, a new line is inserted + */ +template +std::string encode(const std::vector& data, const std::string& label, + size_t line_width = 64) { + return encode(data.data(), data.size(), label, line_width); } -} +/** + * Decode PEM data + * @param pem a datasource containing PEM encoded data + * @param label is set to the PEM label found for later inspection + */ +BOTAN_PUBLIC_API(2, 0) secure_vector decode(DataSource& pem, std::string& label); + +/** + * Decode PEM data + * @param pem a string containing PEM encoded data + * @param label is set to the PEM label found for later inspection + */ +BOTAN_PUBLIC_API(2, 0) secure_vector decode(const std::string& pem, std::string& label); + +/** + * Decode PEM data + * @param pem a datasource containing PEM encoded data + * @param label is what we expect the label to be + */ +BOTAN_PUBLIC_API(2, 0) +secure_vector decode_check_label(DataSource& pem, const std::string& label); + +/** + * Decode PEM data + * @param pem a string containing PEM encoded data + * @param label is what we expect the label to be + */ +BOTAN_PUBLIC_API(2, 0) +secure_vector decode_check_label(const std::string& pem, const std::string& label); + +/** + * Heuristic test for PEM data. + */ +BOTAN_PUBLIC_API(2, 0) +bool matches(DataSource& source, const std::string& extra = "", size_t search_range = 4096); + +} // namespace PEM_Code + +} // namespace Botan namespace Botan { namespace PK_Ops { @@ -11495,364 +10563,340 @@ class Key_Agreement; class KEM_Encryption; class KEM_Decryption; -} +} // namespace PK_Ops -} +} // namespace Botan namespace Botan { class RandomNumberGenerator; /** -* The two types of signature format supported by Botan. -*/ + * The two types of signature format supported by Botan. + */ enum Signature_Format { IEEE_1363, DER_SEQUENCE }; /** -* Public Key Base Class. -*/ -class BOTAN_PUBLIC_API(2,0) Public_Key - { + * Public Key Base Class. + */ +class BOTAN_PUBLIC_API(2, 0) Public_Key { public: - Public_Key() =default; - Public_Key(const Public_Key& other) = default; - Public_Key& operator=(const Public_Key& other) = default; - virtual ~Public_Key() = default; + Public_Key() = default; + Public_Key(const Public_Key& other) = default; + Public_Key& operator=(const Public_Key& other) = default; + virtual ~Public_Key() = default; - /** - * Get the name of the underlying public key scheme. - * @return name of the public key scheme - */ - virtual std::string algo_name() const = 0; + /** + * Get the name of the underlying public key scheme. + * @return name of the public key scheme + */ + virtual std::string algo_name() const = 0; - /** - * Return the estimated strength of the underlying key against - * the best currently known attack. Note that this ignores anything - * but pure attacks against the key itself and do not take into - * account padding schemes, usage mistakes, etc which might reduce - * the strength. However it does suffice to provide an upper bound. - * - * @return estimated strength in bits - */ - virtual size_t estimated_strength() const = 0; + /** + * Return the estimated strength of the underlying key against + * the best currently known attack. Note that this ignores anything + * but pure attacks against the key itself and do not take into + * account padding schemes, usage mistakes, etc which might reduce + * the strength. However it does suffice to provide an upper bound. + * + * @return estimated strength in bits + */ + virtual size_t estimated_strength() const = 0; - /** - * Return an integer value best approximating the length of the - * primary security parameter. For example for RSA this will be - * the size of the modulus, for ECDSA the size of the ECC group, - * and for McEliece the size of the code will be returned. - */ - virtual size_t key_length() const = 0; + /** + * Return an integer value best approximating the length of the + * primary security parameter. For example for RSA this will be + * the size of the modulus, for ECDSA the size of the ECC group, + * and for McEliece the size of the code will be returned. + */ + virtual size_t key_length() const = 0; - /** - * Get the OID of the underlying public key scheme. - * @return OID of the public key scheme - */ - virtual OID get_oid() const; + /** + * Get the OID of the underlying public key scheme. + * @return OID of the public key scheme + */ + virtual OID get_oid() const; - /** - * Test the key values for consistency. - * @param rng rng to use - * @param strong whether to perform strong and lengthy version - * of the test - * @return true if the test is passed - */ - virtual bool check_key(RandomNumberGenerator& rng, - bool strong) const = 0; + /** + * Test the key values for consistency. + * @param rng rng to use + * @param strong whether to perform strong and lengthy version + * of the test + * @return true if the test is passed + */ + virtual bool check_key(RandomNumberGenerator& rng, bool strong) const = 0; + /** + * @return X.509 AlgorithmIdentifier for this key + */ + virtual AlgorithmIdentifier algorithm_identifier() const = 0; - /** - * @return X.509 AlgorithmIdentifier for this key - */ - virtual AlgorithmIdentifier algorithm_identifier() const = 0; + /** + * @return BER encoded public key bits + */ + virtual std::vector public_key_bits() const = 0; - /** - * @return BER encoded public key bits - */ - virtual std::vector public_key_bits() const = 0; + /** + * @return X.509 subject key encoding for this key object + */ + std::vector subject_public_key() const; - /** - * @return X.509 subject key encoding for this key object - */ - std::vector subject_public_key() const; + /** + * @return Hash of the subject public key + */ + std::string fingerprint_public(const std::string& alg = "SHA-256") const; - /** - * @return Hash of the subject public key - */ - std::string fingerprint_public(const std::string& alg = "SHA-256") const; + // Internal or non-public declarations follow - // Internal or non-public declarations follow + /** + * Returns more than 1 if the output of this algorithm + * (ciphertext, signature) should be treated as more than one + * value. This is used for algorithms like DSA and ECDSA, where + * the (r,s) output pair can be encoded as either a plain binary + * list or a TLV tagged DER encoding depending on the protocol. + * + * This function is public but applications should have few + * reasons to ever call this. + * + * @return number of message parts + */ + virtual size_t message_parts() const { return 1; } - /** - * Returns more than 1 if the output of this algorithm - * (ciphertext, signature) should be treated as more than one - * value. This is used for algorithms like DSA and ECDSA, where - * the (r,s) output pair can be encoded as either a plain binary - * list or a TLV tagged DER encoding depending on the protocol. - * - * This function is public but applications should have few - * reasons to ever call this. - * - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } + /** + * Returns how large each of the message parts refered to + * by message_parts() is + * + * This function is public but applications should have few + * reasons to ever call this. + * + * @return size of the message parts in bits + */ + virtual size_t message_part_size() const { return 0; } - /** - * Returns how large each of the message parts refered to - * by message_parts() is - * - * This function is public but applications should have few - * reasons to ever call this. - * - * @return size of the message parts in bits - */ - virtual size_t message_part_size() const { return 0; } + virtual Signature_Format default_x509_signature_format() const { + return (this->message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; + } - virtual Signature_Format default_x509_signature_format() const - { - return (this->message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; - } + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return an encryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr create_encryption_op( + RandomNumberGenerator& rng, const std::string& params, const std::string& provider) const; - /** - * This is an internal library function exposed on key types. - * In almost all cases applications should use wrappers in pubkey.h - * - * Return an encryption operation for this key/params or throw - * - * @param rng a random number generator. The PK_Op may maintain a - * reference to the RNG and use it many times. The rng must outlive - * any operations which reference it. - * @param params additional parameters - * @param provider the provider to use - */ - virtual std::unique_ptr - create_encryption_op(RandomNumberGenerator& rng, - const std::string& params, - const std::string& provider) const; + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a KEM encryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr create_kem_encryption_op( + RandomNumberGenerator& rng, const std::string& params, const std::string& provider) const; - /** - * This is an internal library function exposed on key types. - * In almost all cases applications should use wrappers in pubkey.h - * - * Return a KEM encryption operation for this key/params or throw - * - * @param rng a random number generator. The PK_Op may maintain a - * reference to the RNG and use it many times. The rng must outlive - * any operations which reference it. - * @param params additional parameters - * @param provider the provider to use - */ - virtual std::unique_ptr - create_kem_encryption_op(RandomNumberGenerator& rng, - const std::string& params, - const std::string& provider) const; - - /** - * This is an internal library function exposed on key types. - * In almost all cases applications should use wrappers in pubkey.h - * - * Return a verification operation for this key/params or throw - * @param params additional parameters - * @param provider the provider to use - */ - virtual std::unique_ptr - create_verification_op(const std::string& params, - const std::string& provider) const; - }; + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a verification operation for this key/params or throw + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr create_verification_op( + const std::string& params, const std::string& provider) const; +}; /** -* Private Key Base Class -*/ -class BOTAN_PUBLIC_API(2,0) Private_Key : public virtual Public_Key - { + * Private Key Base Class + */ +class BOTAN_PUBLIC_API(2, 0) Private_Key : public virtual Public_Key { public: - Private_Key() = default; - Private_Key(const Private_Key& other) = default; - Private_Key& operator=(const Private_Key& other) = default; - virtual ~Private_Key() = default; + Private_Key() = default; + Private_Key(const Private_Key& other) = default; + Private_Key& operator=(const Private_Key& other) = default; + virtual ~Private_Key() = default; - virtual bool stateful_operation() const { return false; } + virtual bool stateful_operation() const { return false; } - /** - * @return BER encoded private key bits - */ - virtual secure_vector private_key_bits() const = 0; + /** + * @return BER encoded private key bits + */ + virtual secure_vector private_key_bits() const = 0; - /** - * @return PKCS #8 private key encoding for this key object - */ - secure_vector private_key_info() const; + /** + * @return PKCS #8 private key encoding for this key object + */ + secure_vector private_key_info() const; - /** - * @return PKCS #8 AlgorithmIdentifier for this key - * Might be different from the X.509 identifier, but normally is not - */ - virtual AlgorithmIdentifier pkcs8_algorithm_identifier() const - { return algorithm_identifier(); } + /** + * @return PKCS #8 AlgorithmIdentifier for this key + * Might be different from the X.509 identifier, but normally is not + */ + virtual AlgorithmIdentifier pkcs8_algorithm_identifier() const { + return algorithm_identifier(); + } - // Internal or non-public declarations follow + // Internal or non-public declarations follow - /** - * @return Hash of the PKCS #8 encoding for this key object - */ - std::string fingerprint_private(const std::string& alg) const; + /** + * @return Hash of the PKCS #8 encoding for this key object + */ + std::string fingerprint_private(const std::string& alg) const; - BOTAN_DEPRECATED("Use fingerprint_private or fingerprint_public") - inline std::string fingerprint(const std::string& alg) const - { - return fingerprint_private(alg); // match behavior in previous versions - } + BOTAN_DEPRECATED("Use fingerprint_private or fingerprint_public") + inline std::string fingerprint(const std::string& alg) const { + return fingerprint_private(alg); // match behavior in previous versions + } - /** - * This is an internal library function exposed on key types. - * In almost all cases applications should use wrappers in pubkey.h - * - * Return an decryption operation for this key/params or throw - * - * @param rng a random number generator. The PK_Op may maintain a - * reference to the RNG and use it many times. The rng must outlive - * any operations which reference it. - * @param params additional parameters - * @param provider the provider to use - * - */ - virtual std::unique_ptr - create_decryption_op(RandomNumberGenerator& rng, - const std::string& params, - const std::string& provider) const; + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return an decryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + * + */ + virtual std::unique_ptr create_decryption_op( + RandomNumberGenerator& rng, const std::string& params, const std::string& provider) const; - /** - * This is an internal library function exposed on key types. - * In almost all cases applications should use wrappers in pubkey.h - * - * Return a KEM decryption operation for this key/params or throw - * - * @param rng a random number generator. The PK_Op may maintain a - * reference to the RNG and use it many times. The rng must outlive - * any operations which reference it. - * @param params additional parameters - * @param provider the provider to use - */ - virtual std::unique_ptr - create_kem_decryption_op(RandomNumberGenerator& rng, - const std::string& params, - const std::string& provider) const; + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a KEM decryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr create_kem_decryption_op( + RandomNumberGenerator& rng, const std::string& params, const std::string& provider) const; - /** - * This is an internal library function exposed on key types. - * In almost all cases applications should use wrappers in pubkey.h - * - * Return a signature operation for this key/params or throw - * - * @param rng a random number generator. The PK_Op may maintain a - * reference to the RNG and use it many times. The rng must outlive - * any operations which reference it. - * @param params additional parameters - * @param provider the provider to use - */ - virtual std::unique_ptr - create_signature_op(RandomNumberGenerator& rng, - const std::string& params, - const std::string& provider) const; + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a signature operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr create_signature_op( + RandomNumberGenerator& rng, const std::string& params, const std::string& provider) const; - /** - * This is an internal library function exposed on key types. - * In almost all cases applications should use wrappers in pubkey.h - * - * Return a key agreement operation for this key/params or throw - * - * @param rng a random number generator. The PK_Op may maintain a - * reference to the RNG and use it many times. The rng must outlive - * any operations which reference it. - * @param params additional parameters - * @param provider the provider to use - */ - virtual std::unique_ptr - create_key_agreement_op(RandomNumberGenerator& rng, - const std::string& params, - const std::string& provider) const; - }; + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a key agreement operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr create_key_agreement_op( + RandomNumberGenerator& rng, const std::string& params, const std::string& provider) const; +}; /** -* PK Secret Value Derivation Key -*/ -class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement_Key : public virtual Private_Key - { + * PK Secret Value Derivation Key + */ +class BOTAN_PUBLIC_API(2, 0) PK_Key_Agreement_Key : public virtual Private_Key { public: - /* - * @return public component of this key - */ - virtual std::vector public_value() const = 0; + /* + * @return public component of this key + */ + virtual std::vector public_value() const = 0; - PK_Key_Agreement_Key() = default; - PK_Key_Agreement_Key(const PK_Key_Agreement_Key&) = default; - PK_Key_Agreement_Key& operator=(const PK_Key_Agreement_Key&) = default; - virtual ~PK_Key_Agreement_Key() = default; - }; + PK_Key_Agreement_Key() = default; + PK_Key_Agreement_Key(const PK_Key_Agreement_Key&) = default; + PK_Key_Agreement_Key& operator=(const PK_Key_Agreement_Key&) = default; + virtual ~PK_Key_Agreement_Key() = default; +}; /* -* Old compat typedefs -* TODO: remove these? -*/ + * Old compat typedefs + * TODO: remove these? + */ typedef PK_Key_Agreement_Key PK_KA_Key; typedef Public_Key X509_PublicKey; typedef Private_Key PKCS8_PrivateKey; -std::string BOTAN_PUBLIC_API(2,4) - create_hex_fingerprint(const uint8_t bits[], size_t len, - const std::string& hash_name); +std::string BOTAN_PUBLIC_API(2, 4) + create_hex_fingerprint(const uint8_t bits[], size_t len, const std::string& hash_name); -template +template std::string create_hex_fingerprint(const std::vector& vec, - const std::string& hash_name) - { - return create_hex_fingerprint(vec.data(), vec.size(), hash_name); - } - - + const std::string& hash_name) { + return create_hex_fingerprint(vec.data(), vec.size(), hash_name); } +} // namespace Botan + namespace Botan { -BOTAN_PUBLIC_API(2,0) std::unique_ptr -load_public_key(const AlgorithmIdentifier& alg_id, - const std::vector& key_bits); +BOTAN_PUBLIC_API(2, 0) +std::unique_ptr load_public_key(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits); -BOTAN_PUBLIC_API(2,0) std::unique_ptr -load_private_key(const AlgorithmIdentifier& alg_id, - const secure_vector& key_bits); +BOTAN_PUBLIC_API(2, 0) +std::unique_ptr load_private_key(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits); /** -* Create a new key -* For ECC keys, algo_params specifies EC group (eg, "secp256r1") -* For DH/DSA/ElGamal keys, algo_params is DL group (eg, "modp/ietf/2048") -* For RSA, algo_params is integer keylength -* For McEliece, algo_params is n,t -* If algo_params is left empty, suitable default parameters are chosen. -*/ -BOTAN_PUBLIC_API(2,0) std::unique_ptr -create_private_key(const std::string& algo_name, - RandomNumberGenerator& rng, - const std::string& algo_params = "", - const std::string& provider = ""); + * Create a new key + * For ECC keys, algo_params specifies EC group (eg, "secp256r1") + * For DH/DSA/ElGamal keys, algo_params is DL group (eg, "modp/ietf/2048") + * For RSA, algo_params is integer keylength + * For McEliece, algo_params is n,t + * If algo_params is left empty, suitable default parameters are chosen. + */ +BOTAN_PUBLIC_API(2, 0) +std::unique_ptr create_private_key(const std::string& algo_name, + RandomNumberGenerator& rng, + const std::string& algo_params = "", + const std::string& provider = ""); -BOTAN_PUBLIC_API(2,2) -std::vector -probe_provider_private_key(const std::string& algo_name, - const std::vector possible); +BOTAN_PUBLIC_API(2, 2) +std::vector probe_provider_private_key(const std::string& algo_name, + const std::vector possible); -} +} // namespace Botan /** -* Ordinary applications should never need to include or use this -* header. It is exposed only for specialized applications which want -* to implement new versions of public key crypto without merging them -* as changes to the library. One actual example of such usage is an -* application which creates RSA signatures using a custom TPM library. -* Unless you're doing something like that, you don't need anything -* here. Instead use pubkey.h which wraps these types safely and -* provides a stable application-oriented API. -*/ - + * Ordinary applications should never need to include or use this + * header. It is exposed only for specialized applications which want + * to implement new versions of public key crypto without merging them + * as changes to the library. One actual example of such usage is an + * application which creates RSA signatures using a custom TPM library. + * Unless you're doing something like that, you don't need anything + * here. Instead use pubkey.h which wraps these types safely and + * provides a stable application-oriented API. + */ namespace Botan { @@ -11864,132 +10908,119 @@ class EMSA; namespace PK_Ops { /** -* Public key encryption interface -*/ -class BOTAN_PUBLIC_API(2,0) Encryption - { + * Public key encryption interface + */ +class BOTAN_PUBLIC_API(2, 0) Encryption { public: - virtual secure_vector encrypt(const uint8_t msg[], - size_t msg_len, - RandomNumberGenerator& rng) = 0; + virtual secure_vector encrypt(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) = 0; - virtual size_t max_input_bits() const = 0; + virtual size_t max_input_bits() const = 0; - virtual size_t ciphertext_length(size_t ptext_len) const = 0; + virtual size_t ciphertext_length(size_t ptext_len) const = 0; - virtual ~Encryption() = default; - }; + virtual ~Encryption() = default; +}; /** -* Public key decryption interface -*/ -class BOTAN_PUBLIC_API(2,0) Decryption - { + * Public key decryption interface + */ +class BOTAN_PUBLIC_API(2, 0) Decryption { public: - virtual secure_vector decrypt(uint8_t& valid_mask, - const uint8_t ciphertext[], - size_t ciphertext_len) = 0; + virtual secure_vector decrypt(uint8_t& valid_mask, const uint8_t ciphertext[], + size_t ciphertext_len) = 0; - virtual size_t plaintext_length(size_t ctext_len) const = 0; + virtual size_t plaintext_length(size_t ctext_len) const = 0; - virtual ~Decryption() = default; - }; + virtual ~Decryption() = default; +}; /** -* Public key signature verification interface -*/ -class BOTAN_PUBLIC_API(2,0) Verification - { + * Public key signature verification interface + */ +class BOTAN_PUBLIC_API(2, 0) Verification { public: - /* - * Add more data to the message currently being signed - * @param msg the message - * @param msg_len the length of msg in bytes - */ - virtual void update(const uint8_t msg[], size_t msg_len) = 0; + /* + * Add more data to the message currently being signed + * @param msg the message + * @param msg_len the length of msg in bytes + */ + virtual void update(const uint8_t msg[], size_t msg_len) = 0; - /* - * Perform a verification operation - * @param rng a random number generator - */ - virtual bool is_valid_signature(const uint8_t sig[], size_t sig_len) = 0; + /* + * Perform a verification operation + * @param rng a random number generator + */ + virtual bool is_valid_signature(const uint8_t sig[], size_t sig_len) = 0; - virtual ~Verification() = default; - }; + virtual ~Verification() = default; +}; /** -* Public key signature creation interface -*/ -class BOTAN_PUBLIC_API(2,0) Signature - { + * Public key signature creation interface + */ +class BOTAN_PUBLIC_API(2, 0) Signature { public: - /* - * Add more data to the message currently being signed - * @param msg the message - * @param msg_len the length of msg in bytes - */ - virtual void update(const uint8_t msg[], size_t msg_len) = 0; + /* + * Add more data to the message currently being signed + * @param msg the message + * @param msg_len the length of msg in bytes + */ + virtual void update(const uint8_t msg[], size_t msg_len) = 0; - /* - * Perform a signature operation - * @param rng a random number generator - */ - virtual secure_vector sign(RandomNumberGenerator& rng) = 0; + /* + * Perform a signature operation + * @param rng a random number generator + */ + virtual secure_vector sign(RandomNumberGenerator& rng) = 0; - /* - * Return an upper bound on the length of the output signature - */ - virtual size_t signature_length() const = 0; + /* + * Return an upper bound on the length of the output signature + */ + virtual size_t signature_length() const = 0; - virtual ~Signature() = default; - }; + virtual ~Signature() = default; +}; /** -* A generic key agreement operation (eg DH or ECDH) -*/ -class BOTAN_PUBLIC_API(2,0) Key_Agreement - { + * A generic key agreement operation (eg DH or ECDH) + */ +class BOTAN_PUBLIC_API(2, 0) Key_Agreement { public: - virtual secure_vector agree(size_t key_len, - const uint8_t other_key[], size_t other_key_len, - const uint8_t salt[], size_t salt_len) = 0; + virtual secure_vector agree(size_t key_len, const uint8_t other_key[], + size_t other_key_len, const uint8_t salt[], + size_t salt_len) = 0; - virtual size_t agreed_value_size() const = 0; + virtual size_t agreed_value_size() const = 0; - virtual ~Key_Agreement() = default; - }; + virtual ~Key_Agreement() = default; +}; /** -* KEM (key encapsulation) -*/ -class BOTAN_PUBLIC_API(2,0) KEM_Encryption - { + * KEM (key encapsulation) + */ +class BOTAN_PUBLIC_API(2, 0) KEM_Encryption { public: - virtual void kem_encrypt(secure_vector& out_encapsulated_key, - secure_vector& out_shared_key, - size_t desired_shared_key_len, - Botan::RandomNumberGenerator& rng, - const uint8_t salt[], - size_t salt_len) = 0; + virtual void kem_encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, const uint8_t salt[], + size_t salt_len) = 0; - virtual ~KEM_Encryption() = default; - }; + virtual ~KEM_Encryption() = default; +}; -class BOTAN_PUBLIC_API(2,0) KEM_Decryption - { +class BOTAN_PUBLIC_API(2, 0) KEM_Decryption { public: - virtual secure_vector kem_decrypt(const uint8_t encap_key[], - size_t len, - size_t desired_shared_key_len, - const uint8_t salt[], - size_t salt_len) = 0; + virtual secure_vector kem_decrypt(const uint8_t encap_key[], size_t len, + size_t desired_shared_key_len, const uint8_t salt[], + size_t salt_len) = 0; - virtual ~KEM_Decryption() = default; - }; + virtual ~KEM_Decryption() = default; +}; -} +} // namespace PK_Ops -} +} // namespace Botan namespace Botan { @@ -11997,381 +11028,359 @@ class DataSource; class RandomNumberGenerator; /** -* PKCS #8 General Exception -*/ -class BOTAN_PUBLIC_API(2,0) PKCS8_Exception final : public Decoding_Error - { + * PKCS #8 General Exception + */ +class BOTAN_PUBLIC_API(2, 0) PKCS8_Exception final : public Decoding_Error { public: - explicit PKCS8_Exception(const std::string& error) : - Decoding_Error("PKCS #8: " + error) {} - }; + explicit PKCS8_Exception(const std::string& error) : Decoding_Error("PKCS #8: " + error) {} +}; /** -* This namespace contains functions for handling PKCS #8 private keys -*/ + * This namespace contains functions for handling PKCS #8 private keys + */ namespace PKCS8 { /** -* BER encode a private key -* @param key the private key to encode -* @return BER encoded key -*/ -BOTAN_PUBLIC_API(2,0) secure_vector BER_encode(const Private_Key& key); + * BER encode a private key + * @param key the private key to encode + * @return BER encoded key + */ +BOTAN_PUBLIC_API(2, 0) secure_vector BER_encode(const Private_Key& key); /** -* Get a string containing a PEM encoded private key. -* @param key the key to encode -* @return encoded key -*/ -BOTAN_PUBLIC_API(2,0) std::string PEM_encode(const Private_Key& key); + * Get a string containing a PEM encoded private key. + * @param key the key to encode + * @return encoded key + */ +BOTAN_PUBLIC_API(2, 0) std::string PEM_encode(const Private_Key& key); /** -* Encrypt a key using PKCS #8 encryption -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param msec number of milliseconds to run the password derivation -* @param pbe_algo the name of the desired password-based encryption -* algorithm; if empty ("") a reasonable (portable/secure) -* default will be chosen. -* @return encrypted key in binary BER form -*/ -BOTAN_PUBLIC_API(2,0) std::vector -BER_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - std::chrono::milliseconds msec = std::chrono::milliseconds(300), - const std::string& pbe_algo = ""); - -/** -* Get a string containing a PEM encoded private key, encrypting it with a -* password. -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param msec number of milliseconds to run the password derivation -* @param pbe_algo the name of the desired password-based encryption -* algorithm; if empty ("") a reasonable (portable/secure) -* default will be chosen. -* @return encrypted key in PEM form -*/ -BOTAN_PUBLIC_API(2,0) std::string -PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - std::chrono::milliseconds msec = std::chrono::milliseconds(300), - const std::string& pbe_algo = ""); - -/** -* Encrypt a key using PKCS #8 encryption and a fixed iteration count -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbkdf_iter number of interations to run PBKDF2 -* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes -* are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". -* If empty a suitable default is chosen. -* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. -* For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. -* @return encrypted key in binary BER form -*/ -BOTAN_PUBLIC_API(2,1) std::vector -BER_encode_encrypted_pbkdf_iter(const Private_Key& key, - RandomNumberGenerator& rng, + * Encrypt a key using PKCS #8 encryption + * @param key the key to encode + * @param rng the rng to use + * @param pass the password to use for encryption + * @param msec number of milliseconds to run the password derivation + * @param pbe_algo the name of the desired password-based encryption + * algorithm; if empty ("") a reasonable (portable/secure) + * default will be chosen. + * @return encrypted key in binary BER form + */ +BOTAN_PUBLIC_API(2, 0) +std::vector BER_encode(const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, - size_t pbkdf_iter, - const std::string& cipher = "", - const std::string& pbkdf_hash = ""); + std::chrono::milliseconds msec = std::chrono::milliseconds(300), + const std::string& pbe_algo = ""); /** -* Get a string containing a PEM encoded private key, encrypting it with a -* password. -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbkdf_iter number of iterations to run PBKDF -* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes -* are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". -* If empty a suitable default is chosen. -* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. -* For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. -* @return encrypted key in PEM form -*/ -BOTAN_PUBLIC_API(2,1) std::string -PEM_encode_encrypted_pbkdf_iter(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - size_t pbkdf_iter, - const std::string& cipher = "", - const std::string& pbkdf_hash = ""); + * Get a string containing a PEM encoded private key, encrypting it with a + * password. + * @param key the key to encode + * @param rng the rng to use + * @param pass the password to use for encryption + * @param msec number of milliseconds to run the password derivation + * @param pbe_algo the name of the desired password-based encryption + * algorithm; if empty ("") a reasonable (portable/secure) + * default will be chosen. + * @return encrypted key in PEM form + */ +BOTAN_PUBLIC_API(2, 0) +std::string PEM_encode(const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, + std::chrono::milliseconds msec = std::chrono::milliseconds(300), + const std::string& pbe_algo = ""); /** -* Encrypt a key using PKCS #8 encryption and a variable iteration count -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbkdf_msec how long to run PBKDF2 -* @param pbkdf_iterations if non-null, set to the number of iterations used -* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes -* are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". -* If empty a suitable default is chosen. -* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. -* For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. -* @return encrypted key in binary BER form -*/ -BOTAN_PUBLIC_API(2,1) std::vector -BER_encode_encrypted_pbkdf_msec(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - std::chrono::milliseconds pbkdf_msec, - size_t* pbkdf_iterations, - const std::string& cipher = "", - const std::string& pbkdf_hash = ""); + * Encrypt a key using PKCS #8 encryption and a fixed iteration count + * @param key the key to encode + * @param rng the rng to use + * @param pass the password to use for encryption + * @param pbkdf_iter number of interations to run PBKDF2 + * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes + * are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". + * If empty a suitable default is chosen. + * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. + * For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. + * @return encrypted key in binary BER form + */ +BOTAN_PUBLIC_API(2, 1) +std::vector BER_encode_encrypted_pbkdf_iter(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, size_t pbkdf_iter, + const std::string& cipher = "", + const std::string& pbkdf_hash = ""); /** -* Get a string containing a PEM encoded private key, encrypting it with a -* password. -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbkdf_msec how long in milliseconds to run PBKDF2 -* @param pbkdf_iterations (output argument) number of iterations of PBKDF -* that ended up being used -* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes -* are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". -* If empty a suitable default is chosen. -* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. -* For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. -* @return encrypted key in PEM form -*/ -BOTAN_PUBLIC_API(2,1) std::string -PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - std::chrono::milliseconds pbkdf_msec, - size_t* pbkdf_iterations, - const std::string& cipher = "", - const std::string& pbkdf_hash = ""); + * Get a string containing a PEM encoded private key, encrypting it with a + * password. + * @param key the key to encode + * @param rng the rng to use + * @param pass the password to use for encryption + * @param pbkdf_iter number of iterations to run PBKDF + * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes + * are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". + * If empty a suitable default is chosen. + * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. + * For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. + * @return encrypted key in PEM form + */ +BOTAN_PUBLIC_API(2, 1) +std::string PEM_encode_encrypted_pbkdf_iter(const Private_Key& key, RandomNumberGenerator& rng, + const std::string& pass, size_t pbkdf_iter, + const std::string& cipher = "", + const std::string& pbkdf_hash = ""); /** -* Load an encrypted key from a data source. -* @param source the data source providing the encoded key -* @param rng ignored for compatibility -* @param get_passphrase a function that returns passphrases -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - std::function get_passphrase); + * Encrypt a key using PKCS #8 encryption and a variable iteration count + * @param key the key to encode + * @param rng the rng to use + * @param pass the password to use for encryption + * @param pbkdf_msec how long to run PBKDF2 + * @param pbkdf_iterations if non-null, set to the number of iterations used + * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes + * are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". + * If empty a suitable default is chosen. + * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. + * For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. + * @return encrypted key in binary BER form + */ +BOTAN_PUBLIC_API(2, 1) +std::vector BER_encode_encrypted_pbkdf_msec( + const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, + std::chrono::milliseconds pbkdf_msec, size_t* pbkdf_iterations, const std::string& cipher = "", + const std::string& pbkdf_hash = ""); + +/** + * Get a string containing a PEM encoded private key, encrypting it with a + * password. + * @param key the key to encode + * @param rng the rng to use + * @param pass the password to use for encryption + * @param pbkdf_msec how long in milliseconds to run PBKDF2 + * @param pbkdf_iterations (output argument) number of iterations of PBKDF + * that ended up being used + * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes + * are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". + * If empty a suitable default is chosen. + * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. + * For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. + * @return encrypted key in PEM form + */ +BOTAN_PUBLIC_API(2, 1) +std::string PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds pbkdf_msec, + size_t* pbkdf_iterations, + const std::string& cipher = "", + const std::string& pbkdf_hash = ""); + +/** + * Load an encrypted key from a data source. + * @param source the data source providing the encoded key + * @param rng ignored for compatibility + * @param get_passphrase a function that returns passphrases + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 0) +Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng, + std::function get_passphrase); /** Load an encrypted key from a data source. -* @param source the data source providing the encoded key -* @param rng ignored for compatibility -* @param pass the passphrase to decrypt the key -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass); + * @param source the data source providing the encoded key + * @param rng ignored for compatibility + * @param pass the passphrase to decrypt the key + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 0) +Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng, const std::string& pass); /** Load an unencrypted key from a data source. -* @param source the data source providing the encoded key -* @param rng ignored for compatibility -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng); + * @param source the data source providing the encoded key + * @param rng ignored for compatibility + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 0) Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng); #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) /** -* Load an encrypted key from a file. -* @param filename the path to the file containing the encoded key -* @param rng ignored for compatibility -* @param get_passphrase a function that returns passphrases -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - std::function get_passphrase); + * Load an encrypted key from a file. + * @param filename the path to the file containing the encoded key + * @param rng ignored for compatibility + * @param get_passphrase a function that returns passphrases + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 0) +Private_Key* load_key(const std::string& filename, RandomNumberGenerator& rng, + std::function get_passphrase); /** Load an encrypted key from a file. -* @param filename the path to the file containing the encoded key -* @param rng ignored for compatibility -* @param pass the passphrase to decrypt the key -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const std::string& pass); + * @param filename the path to the file containing the encoded key + * @param rng ignored for compatibility + * @param pass the passphrase to decrypt the key + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 0) +Private_Key* load_key(const std::string& filename, RandomNumberGenerator& rng, + const std::string& pass); /** Load an unencrypted key from a file. -* @param filename the path to the file containing the encoded key -* @param rng ignored for compatibility -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng); + * @param filename the path to the file containing the encoded key + * @param rng ignored for compatibility + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 0) +Private_Key* load_key(const std::string& filename, RandomNumberGenerator& rng); #endif /** -* Copy an existing encoded key object. -* @param key the key to copy -* @param rng ignored for compatibility -* @return new copy of the key -*/ -BOTAN_PUBLIC_API(2,0) Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng); - + * Copy an existing encoded key object. + * @param key the key to copy + * @param rng ignored for compatibility + * @return new copy of the key + */ +BOTAN_PUBLIC_API(2, 0) Private_Key* copy_key(const Private_Key& key, RandomNumberGenerator& rng); /** -* Load an encrypted key from a data source. -* @param source the data source providing the encoded key -* @param get_passphrase a function that returns passphrases -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,3) + * Load an encrypted key from a data source. + * @param source the data source providing the encoded key + * @param get_passphrase a function that returns passphrases + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 3) std::unique_ptr load_key(DataSource& source, - std::function get_passphrase); + std::function get_passphrase); /** Load an encrypted key from a data source. -* @param source the data source providing the encoded key -* @param pass the passphrase to decrypt the key -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,3) -std::unique_ptr load_key(DataSource& source, - const std::string& pass); + * @param source the data source providing the encoded key + * @param pass the passphrase to decrypt the key + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 3) +std::unique_ptr load_key(DataSource& source, const std::string& pass); /** Load an unencrypted key from a data source. -* @param source the data source providing the encoded key -* @return loaded private key object -*/ -BOTAN_PUBLIC_API(2,3) + * @param source the data source providing the encoded key + * @return loaded private key object + */ +BOTAN_PUBLIC_API(2, 3) std::unique_ptr load_key(DataSource& source); /** -* Copy an existing encoded key object. -* @param key the key to copy -* @return new copy of the key -*/ -BOTAN_PUBLIC_API(2,3) + * Copy an existing encoded key object. + * @param key the key to copy + * @return new copy of the key + */ +BOTAN_PUBLIC_API(2, 3) std::unique_ptr copy_key(const Private_Key& key); -} +} // namespace PKCS8 -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(pow_mod.h) +// BOTAN_FUTURE_INTERNAL_HEADER(pow_mod.h) namespace Botan { class Modular_Exponentiator; /** -* Modular Exponentiator Proxy -*/ -class BOTAN_PUBLIC_API(2,0) Power_Mod - { + * Modular Exponentiator Proxy + */ +class BOTAN_PUBLIC_API(2, 0) Power_Mod { public: + enum Usage_Hints { + NO_HINTS = 0x0000, - enum Usage_Hints { - NO_HINTS = 0x0000, + BASE_IS_FIXED = 0x0001, + BASE_IS_SMALL = 0x0002, + BASE_IS_LARGE = 0x0004, + BASE_IS_2 = 0x0008, - BASE_IS_FIXED = 0x0001, - BASE_IS_SMALL = 0x0002, - BASE_IS_LARGE = 0x0004, - BASE_IS_2 = 0x0008, + EXP_IS_FIXED = 0x0100, + EXP_IS_SMALL = 0x0200, + EXP_IS_LARGE = 0x0400 + }; - EXP_IS_FIXED = 0x0100, - EXP_IS_SMALL = 0x0200, - EXP_IS_LARGE = 0x0400 - }; + /* + * Try to choose a good window size + */ + static size_t window_bits(size_t exp_bits, size_t base_bits, Power_Mod::Usage_Hints hints); - /* - * Try to choose a good window size - */ - static size_t window_bits(size_t exp_bits, size_t base_bits, - Power_Mod::Usage_Hints hints); + /** + * @param modulus the modulus + * @param hints Passed to set_modulus if modulus > 0 + * @param disable_montgomery_arith Disables use of Montgomery + * representation. Likely only useful for testing. + */ + void set_modulus(const BigInt& modulus, Usage_Hints hints = NO_HINTS, + bool disable_montgomery_arith = false) const; - /** - * @param modulus the modulus - * @param hints Passed to set_modulus if modulus > 0 - * @param disable_montgomery_arith Disables use of Montgomery - * representation. Likely only useful for testing. - */ - void set_modulus(const BigInt& modulus, - Usage_Hints hints = NO_HINTS, - bool disable_montgomery_arith = false) const; + /** + * Set the base + */ + void set_base(const BigInt& base) const; - /** - * Set the base - */ - void set_base(const BigInt& base) const; + /** + * Set the exponent + */ + void set_exponent(const BigInt& exponent) const; - /** - * Set the exponent - */ - void set_exponent(const BigInt& exponent) const; + /** + * All three of the above functions must have already been called. + * @return result of g^x%p + */ + BigInt execute() const; - /** - * All three of the above functions must have already been called. - * @return result of g^x%p - */ - BigInt execute() const; + Power_Mod& operator=(const Power_Mod&); - Power_Mod& operator=(const Power_Mod&); + /** + * @param modulus Optionally call set_modulus + * @param hints Passed to set_modulus if modulus > 0 + * @param disable_montgomery_arith Disables use of Montgomery + * representation. Likely only useful for testing. + */ + Power_Mod(const BigInt& modulus = 0, Usage_Hints hints = NO_HINTS, + bool disable_montgomery_arith = false); + Power_Mod(const Power_Mod&); + virtual ~Power_Mod(); - /** - * @param modulus Optionally call set_modulus - * @param hints Passed to set_modulus if modulus > 0 - * @param disable_montgomery_arith Disables use of Montgomery - * representation. Likely only useful for testing. - */ - Power_Mod(const BigInt& modulus = 0, - Usage_Hints hints = NO_HINTS, - bool disable_montgomery_arith = false); - Power_Mod(const Power_Mod&); - virtual ~Power_Mod(); private: - mutable std::unique_ptr m_core; - }; + mutable std::unique_ptr m_core; +}; /** -* Fixed Exponent Modular Exponentiator Proxy -*/ -class BOTAN_PUBLIC_API(2,0) Fixed_Exponent_Power_Mod final : public Power_Mod - { + * Fixed Exponent Modular Exponentiator Proxy + */ +class BOTAN_PUBLIC_API(2, 0) Fixed_Exponent_Power_Mod final : public Power_Mod { public: - BigInt operator()(const BigInt& b) const - { set_base(b); return execute(); } + BigInt operator()(const BigInt& b) const { + set_base(b); + return execute(); + } - Fixed_Exponent_Power_Mod() = default; + Fixed_Exponent_Power_Mod() = default; - Fixed_Exponent_Power_Mod(const BigInt& exponent, - const BigInt& modulus, - Usage_Hints hints = NO_HINTS); - }; + Fixed_Exponent_Power_Mod(const BigInt& exponent, const BigInt& modulus, + Usage_Hints hints = NO_HINTS); +}; /** -* Fixed Base Modular Exponentiator Proxy -*/ -class BOTAN_PUBLIC_API(2,0) Fixed_Base_Power_Mod final : public Power_Mod - { + * Fixed Base Modular Exponentiator Proxy + */ +class BOTAN_PUBLIC_API(2, 0) Fixed_Base_Power_Mod final : public Power_Mod { public: - BigInt operator()(const BigInt& e) const - { set_exponent(e); return execute(); } + BigInt operator()(const BigInt& e) const { + set_exponent(e); + return execute(); + } - Fixed_Base_Power_Mod() = default; + Fixed_Base_Power_Mod() = default; - Fixed_Base_Power_Mod(const BigInt& base, - const BigInt& modulus, - Usage_Hints hints = NO_HINTS); - }; + Fixed_Base_Power_Mod(const BigInt& base, const BigInt& modulus, Usage_Hints hints = NO_HINTS); +}; -} +} // namespace Botan #if defined(BOTAN_HAS_SYSTEM_RNG) - #define BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS +#define BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS #endif namespace Botan { @@ -12379,874 +11388,767 @@ namespace Botan { class RandomNumberGenerator; /** -* Public Key Encryptor -* This is the primary interface for public key encryption -*/ -class BOTAN_PUBLIC_API(2,0) PK_Encryptor - { + * Public Key Encryptor + * This is the primary interface for public key encryption + */ +class BOTAN_PUBLIC_API(2, 0) PK_Encryptor { public: + /** + * Encrypt a message. + * @param in the message as a byte array + * @param length the length of the above byte array + * @param rng the random number source to use + * @return encrypted message + */ + std::vector encrypt(const uint8_t in[], size_t length, + RandomNumberGenerator& rng) const { + return enc(in, length, rng); + } - /** - * Encrypt a message. - * @param in the message as a byte array - * @param length the length of the above byte array - * @param rng the random number source to use - * @return encrypted message - */ - std::vector encrypt(const uint8_t in[], size_t length, - RandomNumberGenerator& rng) const - { - return enc(in, length, rng); - } + /** + * Encrypt a message. + * @param in the message + * @param rng the random number source to use + * @return encrypted message + */ + template + std::vector encrypt(const std::vector& in, + RandomNumberGenerator& rng) const { + return enc(in.data(), in.size(), rng); + } - /** - * Encrypt a message. - * @param in the message - * @param rng the random number source to use - * @return encrypted message - */ - template - std::vector encrypt(const std::vector& in, - RandomNumberGenerator& rng) const - { - return enc(in.data(), in.size(), rng); - } + /** + * Return the maximum allowed message size in bytes. + * @return maximum message size in bytes + */ + virtual size_t maximum_input_size() const = 0; - /** - * Return the maximum allowed message size in bytes. - * @return maximum message size in bytes - */ - virtual size_t maximum_input_size() const = 0; + /** + * Return an upper bound on the ciphertext length + */ + virtual size_t ciphertext_length(size_t ctext_len) const = 0; - /** - * Return an upper bound on the ciphertext length - */ - virtual size_t ciphertext_length(size_t ctext_len) const = 0; + PK_Encryptor() = default; + virtual ~PK_Encryptor() = default; - PK_Encryptor() = default; - virtual ~PK_Encryptor() = default; - - PK_Encryptor(const PK_Encryptor&) = delete; - PK_Encryptor& operator=(const PK_Encryptor&) = delete; + PK_Encryptor(const PK_Encryptor&) = delete; + PK_Encryptor& operator=(const PK_Encryptor&) = delete; private: - virtual std::vector enc(const uint8_t[], size_t, - RandomNumberGenerator&) const = 0; - }; + virtual std::vector enc(const uint8_t[], size_t, RandomNumberGenerator&) const = 0; +}; /** -* Public Key Decryptor -*/ -class BOTAN_PUBLIC_API(2,0) PK_Decryptor - { + * Public Key Decryptor + */ +class BOTAN_PUBLIC_API(2, 0) PK_Decryptor { public: - /** - * Decrypt a ciphertext, throwing an exception if the input - * seems to be invalid (eg due to an accidental or malicious - * error in the ciphertext). - * - * @param in the ciphertext as a byte array - * @param length the length of the above byte array - * @return decrypted message - */ - secure_vector decrypt(const uint8_t in[], size_t length) const; + /** + * Decrypt a ciphertext, throwing an exception if the input + * seems to be invalid (eg due to an accidental or malicious + * error in the ciphertext). + * + * @param in the ciphertext as a byte array + * @param length the length of the above byte array + * @return decrypted message + */ + secure_vector decrypt(const uint8_t in[], size_t length) const; - /** - * Same as above, but taking a vector - * @param in the ciphertext - * @return decrypted message - */ - template - secure_vector decrypt(const std::vector& in) const - { - return decrypt(in.data(), in.size()); - } + /** + * Same as above, but taking a vector + * @param in the ciphertext + * @return decrypted message + */ + template + secure_vector decrypt(const std::vector& in) const { + return decrypt(in.data(), in.size()); + } - /** - * Decrypt a ciphertext. If the ciphertext is invalid (eg due to - * invalid padding) or is not the expected length, instead - * returns a random string of the expected length. Use to avoid - * oracle attacks, especially against PKCS #1 v1.5 decryption. - */ - secure_vector - decrypt_or_random(const uint8_t in[], - size_t length, - size_t expected_pt_len, - RandomNumberGenerator& rng) const; + /** + * Decrypt a ciphertext. If the ciphertext is invalid (eg due to + * invalid padding) or is not the expected length, instead + * returns a random string of the expected length. Use to avoid + * oracle attacks, especially against PKCS #1 v1.5 decryption. + */ + secure_vector decrypt_or_random(const uint8_t in[], size_t length, + size_t expected_pt_len, + RandomNumberGenerator& rng) const; - /** - * Decrypt a ciphertext. If the ciphertext is invalid (eg due to - * invalid padding) or is not the expected length, instead - * returns a random string of the expected length. Use to avoid - * oracle attacks, especially against PKCS #1 v1.5 decryption. - * - * Additionally checks (also in const time) that: - * contents[required_content_offsets[i]] == required_content_bytes[i] - * for 0 <= i < required_contents - * - * Used for example in TLS, which encodes the client version in - * the content bytes: if there is any timing variation the version - * check can be used as an oracle to recover the key. - */ - secure_vector - decrypt_or_random(const uint8_t in[], - size_t length, - size_t expected_pt_len, - RandomNumberGenerator& rng, - const uint8_t required_content_bytes[], - const uint8_t required_content_offsets[], - size_t required_contents) const; + /** + * Decrypt a ciphertext. If the ciphertext is invalid (eg due to + * invalid padding) or is not the expected length, instead + * returns a random string of the expected length. Use to avoid + * oracle attacks, especially against PKCS #1 v1.5 decryption. + * + * Additionally checks (also in const time) that: + * contents[required_content_offsets[i]] == required_content_bytes[i] + * for 0 <= i < required_contents + * + * Used for example in TLS, which encodes the client version in + * the content bytes: if there is any timing variation the version + * check can be used as an oracle to recover the key. + */ + secure_vector decrypt_or_random(const uint8_t in[], size_t length, + size_t expected_pt_len, RandomNumberGenerator& rng, + const uint8_t required_content_bytes[], + const uint8_t required_content_offsets[], + size_t required_contents) const; - /** - * Return an upper bound on the plaintext length for a particular - * ciphertext input length - */ - virtual size_t plaintext_length(size_t ctext_len) const = 0; + /** + * Return an upper bound on the plaintext length for a particular + * ciphertext input length + */ + virtual size_t plaintext_length(size_t ctext_len) const = 0; - PK_Decryptor() = default; - virtual ~PK_Decryptor() = default; + PK_Decryptor() = default; + virtual ~PK_Decryptor() = default; - PK_Decryptor(const PK_Decryptor&) = delete; - PK_Decryptor& operator=(const PK_Decryptor&) = delete; + PK_Decryptor(const PK_Decryptor&) = delete; + PK_Decryptor& operator=(const PK_Decryptor&) = delete; private: - virtual secure_vector do_decrypt(uint8_t& valid_mask, - const uint8_t in[], size_t in_len) const = 0; - }; + virtual secure_vector do_decrypt(uint8_t& valid_mask, const uint8_t in[], + size_t in_len) const = 0; +}; /** -* Public Key Signer. Use the sign_message() functions for small -* messages. Use multiple calls update() to process large messages and -* generate the signature by finally calling signature(). -*/ -class BOTAN_PUBLIC_API(2,0) PK_Signer final - { + * Public Key Signer. Use the sign_message() functions for small + * messages. Use multiple calls update() to process large messages and + * generate the signature by finally calling signature(). + */ +class BOTAN_PUBLIC_API(2, 0) PK_Signer final { public: - - /** - * Construct a PK Signer. - * @param key the key to use inside this signer - * @param rng the random generator to use - * @param emsa the EMSA to use - * An example would be "EMSA1(SHA-224)". - * @param format the signature format to use - * @param provider the provider to use - */ - PK_Signer(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& emsa, - Signature_Format format = IEEE_1363, - const std::string& provider = ""); + /** + * Construct a PK Signer. + * @param key the key to use inside this signer + * @param rng the random generator to use + * @param emsa the EMSA to use + * An example would be "EMSA1(SHA-224)". + * @param format the signature format to use + * @param provider the provider to use + */ + PK_Signer(const Private_Key& key, RandomNumberGenerator& rng, const std::string& emsa, + Signature_Format format = IEEE_1363, const std::string& provider = ""); #if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) - /** - * Construct a PK Signer. - * @param key the key to use inside this signer - * @param emsa the EMSA to use - * An example would be "EMSA1(SHA-224)". - * @param format the signature format to use - */ - BOTAN_DEPRECATED("Use constructor taking a RNG object") - PK_Signer(const Private_Key& key, - const std::string& emsa, - Signature_Format format = IEEE_1363, - const std::string& provider = "") : - PK_Signer(key, system_rng(), emsa, format, provider) - {} + /** + * Construct a PK Signer. + * @param key the key to use inside this signer + * @param emsa the EMSA to use + * An example would be "EMSA1(SHA-224)". + * @param format the signature format to use + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Signer(const Private_Key& key, const std::string& emsa, Signature_Format format = IEEE_1363, + const std::string& provider = "") + : PK_Signer(key, system_rng(), emsa, format, provider) {} #endif - ~PK_Signer(); + ~PK_Signer(); - PK_Signer(const PK_Signer&) = delete; - PK_Signer& operator=(const PK_Signer&) = delete; + PK_Signer(const PK_Signer&) = delete; + PK_Signer& operator=(const PK_Signer&) = delete; - /** - * Sign a message all in one go - * @param in the message to sign as a byte array - * @param length the length of the above byte array - * @param rng the rng to use - * @return signature - */ - std::vector sign_message(const uint8_t in[], size_t length, - RandomNumberGenerator& rng) - { - this->update(in, length); - return this->signature(rng); - } + /** + * Sign a message all in one go + * @param in the message to sign as a byte array + * @param length the length of the above byte array + * @param rng the rng to use + * @return signature + */ + std::vector sign_message(const uint8_t in[], size_t length, + RandomNumberGenerator& rng) { + this->update(in, length); + return this->signature(rng); + } - /** - * Sign a message. - * @param in the message to sign - * @param rng the rng to use - * @return signature - */ - template - std::vector sign_message(const std::vector& in, - RandomNumberGenerator& rng) - { - return sign_message(in.data(), in.size(), rng); - } + /** + * Sign a message. + * @param in the message to sign + * @param rng the rng to use + * @return signature + */ + template + std::vector sign_message(const std::vector& in, + RandomNumberGenerator& rng) { + return sign_message(in.data(), in.size(), rng); + } - /** - * Add a message part (single byte). - * @param in the byte to add - */ - void update(uint8_t in) { update(&in, 1); } + /** + * Add a message part (single byte). + * @param in the byte to add + */ + void update(uint8_t in) { update(&in, 1); } - /** - * Add a message part. - * @param in the message part to add as a byte array - * @param length the length of the above byte array - */ - void update(const uint8_t in[], size_t length); + /** + * Add a message part. + * @param in the message part to add as a byte array + * @param length the length of the above byte array + */ + void update(const uint8_t in[], size_t length); - /** - * Add a message part. - * @param in the message part to add - */ - template - void update(const std::vector& in) - { - update(in.data(), in.size()); - } + /** + * Add a message part. + * @param in the message part to add + */ + template + void update(const std::vector& in) { + update(in.data(), in.size()); + } - /** - * Add a message part. - * @param in the message part to add - */ - void update(const std::string& in) - { - update(cast_char_ptr_to_uint8(in.data()), in.size()); - } + /** + * Add a message part. + * @param in the message part to add + */ + void update(const std::string& in) { update(cast_char_ptr_to_uint8(in.data()), in.size()); } - /** - * Get the signature of the so far processed message (provided by the - * calls to update()). - * @param rng the rng to use - * @return signature of the total message - */ - std::vector signature(RandomNumberGenerator& rng); + /** + * Get the signature of the so far processed message (provided by the + * calls to update()). + * @param rng the rng to use + * @return signature of the total message + */ + std::vector signature(RandomNumberGenerator& rng); + /** + * Set the output format of the signature. + * @param format the signature format to use + */ + void set_output_format(Signature_Format format) { m_sig_format = format; } - /** - * Set the output format of the signature. - * @param format the signature format to use - */ - void set_output_format(Signature_Format format) { m_sig_format = format; } - - /** - * Return an upper bound on the length of the signatures this - * PK_Signer will produce - */ - size_t signature_length() const; + /** + * Return an upper bound on the length of the signatures this + * PK_Signer will produce + */ + size_t signature_length() const; private: - std::unique_ptr m_op; - Signature_Format m_sig_format; - size_t m_parts, m_part_size; - }; + std::unique_ptr m_op; + Signature_Format m_sig_format; + size_t m_parts, m_part_size; +}; /** -* Public Key Verifier. Use the verify_message() functions for small -* messages. Use multiple calls update() to process large messages and -* verify the signature by finally calling check_signature(). -*/ -class BOTAN_PUBLIC_API(2,0) PK_Verifier final - { + * Public Key Verifier. Use the verify_message() functions for small + * messages. Use multiple calls update() to process large messages and + * verify the signature by finally calling check_signature(). + */ +class BOTAN_PUBLIC_API(2, 0) PK_Verifier final { public: - /** - * Construct a PK Verifier. - * @param pub_key the public key to verify against - * @param emsa the EMSA to use (eg "EMSA3(SHA-1)") - * @param format the signature format to use - * @param provider the provider to use - */ - PK_Verifier(const Public_Key& pub_key, - const std::string& emsa, - Signature_Format format = IEEE_1363, - const std::string& provider = ""); + /** + * Construct a PK Verifier. + * @param pub_key the public key to verify against + * @param emsa the EMSA to use (eg "EMSA3(SHA-1)") + * @param format the signature format to use + * @param provider the provider to use + */ + PK_Verifier(const Public_Key& pub_key, const std::string& emsa, + Signature_Format format = IEEE_1363, const std::string& provider = ""); - ~PK_Verifier(); + ~PK_Verifier(); - PK_Verifier& operator=(const PK_Verifier&) = delete; - PK_Verifier(const PK_Verifier&) = delete; + PK_Verifier& operator=(const PK_Verifier&) = delete; + PK_Verifier(const PK_Verifier&) = delete; - /** - * Verify a signature. - * @param msg the message that the signature belongs to, as a byte array - * @param msg_length the length of the above byte array msg - * @param sig the signature as a byte array - * @param sig_length the length of the above byte array sig - * @return true if the signature is valid - */ - bool verify_message(const uint8_t msg[], size_t msg_length, - const uint8_t sig[], size_t sig_length); - /** - * Verify a signature. - * @param msg the message that the signature belongs to - * @param sig the signature - * @return true if the signature is valid - */ - template - bool verify_message(const std::vector& msg, - const std::vector& sig) - { - return verify_message(msg.data(), msg.size(), - sig.data(), sig.size()); - } + /** + * Verify a signature. + * @param msg the message that the signature belongs to, as a byte array + * @param msg_length the length of the above byte array msg + * @param sig the signature as a byte array + * @param sig_length the length of the above byte array sig + * @return true if the signature is valid + */ + bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], + size_t sig_length); + /** + * Verify a signature. + * @param msg the message that the signature belongs to + * @param sig the signature + * @return true if the signature is valid + */ + template + bool verify_message(const std::vector& msg, + const std::vector& sig) { + return verify_message(msg.data(), msg.size(), sig.data(), sig.size()); + } - /** - * Add a message part (single byte) of the message corresponding to the - * signature to be verified. - * @param in the byte to add - */ - void update(uint8_t in) { update(&in, 1); } + /** + * Add a message part (single byte) of the message corresponding to the + * signature to be verified. + * @param in the byte to add + */ + void update(uint8_t in) { update(&in, 1); } - /** - * Add a message part of the message corresponding to the - * signature to be verified. - * @param msg_part the new message part as a byte array - * @param length the length of the above byte array - */ - void update(const uint8_t msg_part[], size_t length); + /** + * Add a message part of the message corresponding to the + * signature to be verified. + * @param msg_part the new message part as a byte array + * @param length the length of the above byte array + */ + void update(const uint8_t msg_part[], size_t length); - /** - * Add a message part of the message corresponding to the - * signature to be verified. - * @param in the new message part - */ - template - void update(const std::vector& in) - { - update(in.data(), in.size()); - } + /** + * Add a message part of the message corresponding to the + * signature to be verified. + * @param in the new message part + */ + template + void update(const std::vector& in) { + update(in.data(), in.size()); + } - /** - * Add a message part of the message corresponding to the - * signature to be verified. - */ - void update(const std::string& in) - { - update(cast_char_ptr_to_uint8(in.data()), in.size()); - } + /** + * Add a message part of the message corresponding to the + * signature to be verified. + */ + void update(const std::string& in) { update(cast_char_ptr_to_uint8(in.data()), in.size()); } - /** - * Check the signature of the buffered message, i.e. the one build - * by successive calls to update. - * @param sig the signature to be verified as a byte array - * @param length the length of the above byte array - * @return true if the signature is valid, false otherwise - */ - bool check_signature(const uint8_t sig[], size_t length); + /** + * Check the signature of the buffered message, i.e. the one build + * by successive calls to update. + * @param sig the signature to be verified as a byte array + * @param length the length of the above byte array + * @return true if the signature is valid, false otherwise + */ + bool check_signature(const uint8_t sig[], size_t length); - /** - * Check the signature of the buffered message, i.e. the one build - * by successive calls to update. - * @param sig the signature to be verified - * @return true if the signature is valid, false otherwise - */ - template - bool check_signature(const std::vector& sig) - { - return check_signature(sig.data(), sig.size()); - } + /** + * Check the signature of the buffered message, i.e. the one build + * by successive calls to update. + * @param sig the signature to be verified + * @return true if the signature is valid, false otherwise + */ + template + bool check_signature(const std::vector& sig) { + return check_signature(sig.data(), sig.size()); + } - /** - * Set the format of the signatures fed to this verifier. - * @param format the signature format to use - */ - void set_input_format(Signature_Format format); + /** + * Set the format of the signatures fed to this verifier. + * @param format the signature format to use + */ + void set_input_format(Signature_Format format); private: - std::unique_ptr m_op; - Signature_Format m_sig_format; - size_t m_parts, m_part_size; - }; + std::unique_ptr m_op; + Signature_Format m_sig_format; + size_t m_parts, m_part_size; +}; /** -* Object used for key agreement -*/ -class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final - { + * Object used for key agreement + */ +class BOTAN_PUBLIC_API(2, 0) PK_Key_Agreement final { public: - - /** - * Construct a PK Key Agreement. - * @param key the key to use - * @param rng the random generator to use - * @param kdf name of the KDF to use (or 'Raw' for no KDF) - * @param provider the algo provider to use (or empty for default) - */ - PK_Key_Agreement(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& kdf, - const std::string& provider = ""); + /** + * Construct a PK Key Agreement. + * @param key the key to use + * @param rng the random generator to use + * @param kdf name of the KDF to use (or 'Raw' for no KDF) + * @param provider the algo provider to use (or empty for default) + */ + PK_Key_Agreement(const Private_Key& key, RandomNumberGenerator& rng, const std::string& kdf, + const std::string& provider = ""); #if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) - /** - * Construct a PK Key Agreement. - * @param key the key to use - * @param kdf name of the KDF to use (or 'Raw' for no KDF) - * @param provider the algo provider to use (or empty for default) - */ - BOTAN_DEPRECATED("Use constructor taking a RNG object") - PK_Key_Agreement(const Private_Key& key, - const std::string& kdf, - const std::string& provider = "") : - PK_Key_Agreement(key, system_rng(), kdf, provider) - {} + /** + * Construct a PK Key Agreement. + * @param key the key to use + * @param kdf name of the KDF to use (or 'Raw' for no KDF) + * @param provider the algo provider to use (or empty for default) + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Key_Agreement(const Private_Key& key, const std::string& kdf, + const std::string& provider = "") + : PK_Key_Agreement(key, system_rng(), kdf, provider) {} #endif - ~PK_Key_Agreement(); + ~PK_Key_Agreement(); - // For ECIES - PK_Key_Agreement& operator=(PK_Key_Agreement&&); - PK_Key_Agreement(PK_Key_Agreement&&); + // For ECIES + PK_Key_Agreement& operator=(PK_Key_Agreement&&); + PK_Key_Agreement(PK_Key_Agreement&&); - PK_Key_Agreement& operator=(const PK_Key_Agreement&) = delete; - PK_Key_Agreement(const PK_Key_Agreement&) = delete; + PK_Key_Agreement& operator=(const PK_Key_Agreement&) = delete; + PK_Key_Agreement(const PK_Key_Agreement&) = delete; - /** - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param in_len the length of in in bytes - * @param params extra derivation params - * @param params_len the length of params in bytes - */ - SymmetricKey derive_key(size_t key_len, - const uint8_t in[], - size_t in_len, - const uint8_t params[], - size_t params_len) const; + /** + * Perform Key Agreement Operation + * @param key_len the desired key output size + * @param in the other parties key + * @param in_len the length of in in bytes + * @param params extra derivation params + * @param params_len the length of params in bytes + */ + SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, + const uint8_t params[], size_t params_len) const; - /** - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param params extra derivation params - * @param params_len the length of params in bytes - */ - SymmetricKey derive_key(size_t key_len, - const std::vector& in, - const uint8_t params[], - size_t params_len) const - { - return derive_key(key_len, in.data(), in.size(), - params, params_len); - } + /** + * Perform Key Agreement Operation + * @param key_len the desired key output size + * @param in the other parties key + * @param params extra derivation params + * @param params_len the length of params in bytes + */ + SymmetricKey derive_key(size_t key_len, const std::vector& in, const uint8_t params[], + size_t params_len) const { + return derive_key(key_len, in.data(), in.size(), params, params_len); + } - /** - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param in_len the length of in in bytes - * @param params extra derivation params - */ - SymmetricKey derive_key(size_t key_len, - const uint8_t in[], size_t in_len, - const std::string& params = "") const - { - return derive_key(key_len, in, in_len, - cast_char_ptr_to_uint8(params.data()), - params.length()); - } + /** + * Perform Key Agreement Operation + * @param key_len the desired key output size + * @param in the other parties key + * @param in_len the length of in in bytes + * @param params extra derivation params + */ + SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, + const std::string& params = "") const { + return derive_key(key_len, in, in_len, cast_char_ptr_to_uint8(params.data()), + params.length()); + } - /** - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param params extra derivation params - */ - SymmetricKey derive_key(size_t key_len, - const std::vector& in, - const std::string& params = "") const - { - return derive_key(key_len, in.data(), in.size(), - cast_char_ptr_to_uint8(params.data()), - params.length()); - } + /** + * Perform Key Agreement Operation + * @param key_len the desired key output size + * @param in the other parties key + * @param params extra derivation params + */ + SymmetricKey derive_key(size_t key_len, const std::vector& in, + const std::string& params = "") const { + return derive_key(key_len, in.data(), in.size(), cast_char_ptr_to_uint8(params.data()), + params.length()); + } - /** - * Return the underlying size of the value that is agreed. - * If derive_key is called with a length of 0 with a "Raw" - * KDF, it will return a value of this size. - */ - size_t agreed_value_size() const; + /** + * Return the underlying size of the value that is agreed. + * If derive_key is called with a length of 0 with a "Raw" + * KDF, it will return a value of this size. + */ + size_t agreed_value_size() const; private: - std::unique_ptr m_op; - }; + std::unique_ptr m_op; +}; /** -* Encryption using a standard message recovery algorithm like RSA or -* ElGamal, paired with an encoding scheme like OAEP. -*/ -class BOTAN_PUBLIC_API(2,0) PK_Encryptor_EME final : public PK_Encryptor - { + * Encryption using a standard message recovery algorithm like RSA or + * ElGamal, paired with an encoding scheme like OAEP. + */ +class BOTAN_PUBLIC_API(2, 0) PK_Encryptor_EME final : public PK_Encryptor { public: - size_t maximum_input_size() const override; + size_t maximum_input_size() const override; - /** - * Construct an instance. - * @param key the key to use inside the encryptor - * @param rng the RNG to use - * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") - * @param provider the provider to use - */ - PK_Encryptor_EME(const Public_Key& key, - RandomNumberGenerator& rng, - const std::string& padding, - const std::string& provider = ""); + /** + * Construct an instance. + * @param key the key to use inside the encryptor + * @param rng the RNG to use + * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") + * @param provider the provider to use + */ + PK_Encryptor_EME(const Public_Key& key, RandomNumberGenerator& rng, const std::string& padding, + const std::string& provider = ""); #if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) - /** - * Construct an instance. - * @param key the key to use inside the encryptor - * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") - */ - BOTAN_DEPRECATED("Use constructor taking a RNG object") - PK_Encryptor_EME(const Public_Key& key, - const std::string& padding, - const std::string& provider = "") : - PK_Encryptor_EME(key, system_rng(), padding, provider) {} + /** + * Construct an instance. + * @param key the key to use inside the encryptor + * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Encryptor_EME(const Public_Key& key, const std::string& padding, + const std::string& provider = "") + : PK_Encryptor_EME(key, system_rng(), padding, provider) {} #endif - ~PK_Encryptor_EME(); + ~PK_Encryptor_EME(); - PK_Encryptor_EME& operator=(const PK_Encryptor_EME&) = delete; - PK_Encryptor_EME(const PK_Encryptor_EME&) = delete; + PK_Encryptor_EME& operator=(const PK_Encryptor_EME&) = delete; + PK_Encryptor_EME(const PK_Encryptor_EME&) = delete; + + /** + * Return an upper bound on the ciphertext length for a particular + * plaintext input length + */ + size_t ciphertext_length(size_t ptext_len) const override; - /** - * Return an upper bound on the ciphertext length for a particular - * plaintext input length - */ - size_t ciphertext_length(size_t ptext_len) const override; private: - std::vector enc(const uint8_t[], size_t, - RandomNumberGenerator& rng) const override; + std::vector enc(const uint8_t[], size_t, RandomNumberGenerator& rng) const override; - std::unique_ptr m_op; - }; + std::unique_ptr m_op; +}; /** -* Decryption with an MR algorithm and an EME. -*/ -class BOTAN_PUBLIC_API(2,0) PK_Decryptor_EME final : public PK_Decryptor - { + * Decryption with an MR algorithm and an EME. + */ +class BOTAN_PUBLIC_API(2, 0) PK_Decryptor_EME final : public PK_Decryptor { public: - /** - * Construct an instance. - * @param key the key to use inside the decryptor - * @param rng the random generator to use - * @param eme the EME to use - * @param provider the provider to use - */ - PK_Decryptor_EME(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& eme, - const std::string& provider = ""); - + /** + * Construct an instance. + * @param key the key to use inside the decryptor + * @param rng the random generator to use + * @param eme the EME to use + * @param provider the provider to use + */ + PK_Decryptor_EME(const Private_Key& key, RandomNumberGenerator& rng, const std::string& eme, + const std::string& provider = ""); #if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) - /** - * Construct an instance. - * @param key the key to use inside the decryptor - * @param eme the message encoding scheme to use (eg "OAEP(SHA-256)") - */ - BOTAN_DEPRECATED("Use constructor taking a RNG object") - PK_Decryptor_EME(const Private_Key& key, - const std::string& eme, - const std::string& provider = "") : - PK_Decryptor_EME(key, system_rng(), eme, provider) {} + /** + * Construct an instance. + * @param key the key to use inside the decryptor + * @param eme the message encoding scheme to use (eg "OAEP(SHA-256)") + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Decryptor_EME(const Private_Key& key, const std::string& eme, + const std::string& provider = "") + : PK_Decryptor_EME(key, system_rng(), eme, provider) {} #endif - size_t plaintext_length(size_t ptext_len) const override; + size_t plaintext_length(size_t ptext_len) const override; + + ~PK_Decryptor_EME(); + PK_Decryptor_EME& operator=(const PK_Decryptor_EME&) = delete; + PK_Decryptor_EME(const PK_Decryptor_EME&) = delete; - ~PK_Decryptor_EME(); - PK_Decryptor_EME& operator=(const PK_Decryptor_EME&) = delete; - PK_Decryptor_EME(const PK_Decryptor_EME&) = delete; private: - secure_vector do_decrypt(uint8_t& valid_mask, - const uint8_t in[], - size_t in_len) const override; + secure_vector do_decrypt(uint8_t& valid_mask, const uint8_t in[], + size_t in_len) const override; - std::unique_ptr m_op; - }; + std::unique_ptr m_op; +}; /** -* Public Key Key Encapsulation Mechanism Encryption. -*/ -class BOTAN_PUBLIC_API(2,0) PK_KEM_Encryptor final - { + * Public Key Key Encapsulation Mechanism Encryption. + */ +class BOTAN_PUBLIC_API(2, 0) PK_KEM_Encryptor final { public: - /** - * Construct an instance. - * @param key the key to use inside the encryptor - * @param rng the RNG to use - * @param kem_param additional KEM parameters - * @param provider the provider to use - */ - PK_KEM_Encryptor(const Public_Key& key, - RandomNumberGenerator& rng, - const std::string& kem_param = "", - const std::string& provider = ""); + /** + * Construct an instance. + * @param key the key to use inside the encryptor + * @param rng the RNG to use + * @param kem_param additional KEM parameters + * @param provider the provider to use + */ + PK_KEM_Encryptor(const Public_Key& key, RandomNumberGenerator& rng, + const std::string& kem_param = "", const std::string& provider = ""); #if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) - BOTAN_DEPRECATED("Use constructor taking a RNG object") - PK_KEM_Encryptor(const Public_Key& key, - const std::string& kem_param = "", - const std::string& provider = "") : - PK_KEM_Encryptor(key, system_rng(), kem_param, provider) {} + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_KEM_Encryptor(const Public_Key& key, const std::string& kem_param = "", + const std::string& provider = "") + : PK_KEM_Encryptor(key, system_rng(), kem_param, provider) {} #endif - ~PK_KEM_Encryptor(); + ~PK_KEM_Encryptor(); - PK_KEM_Encryptor& operator=(const PK_KEM_Encryptor&) = delete; - PK_KEM_Encryptor(const PK_KEM_Encryptor&) = delete; + PK_KEM_Encryptor& operator=(const PK_KEM_Encryptor&) = delete; + PK_KEM_Encryptor(const PK_KEM_Encryptor&) = delete; - /** - * Generate a shared key for data encryption. - * @param out_encapsulated_key the generated encapsulated key - * @param out_shared_key the generated shared key - * @param desired_shared_key_len desired size of the shared key in bytes - * @param rng the RNG to use - * @param salt a salt value used in the KDF - * @param salt_len size of the salt value in bytes - */ - void encrypt(secure_vector& out_encapsulated_key, - secure_vector& out_shared_key, - size_t desired_shared_key_len, - Botan::RandomNumberGenerator& rng, - const uint8_t salt[], - size_t salt_len); + /** + * Generate a shared key for data encryption. + * @param out_encapsulated_key the generated encapsulated key + * @param out_shared_key the generated shared key + * @param desired_shared_key_len desired size of the shared key in bytes + * @param rng the RNG to use + * @param salt a salt value used in the KDF + * @param salt_len size of the salt value in bytes + */ + void encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, const uint8_t salt[], size_t salt_len); - /** - * Generate a shared key for data encryption. - * @param out_encapsulated_key the generated encapsulated key - * @param out_shared_key the generated shared key - * @param desired_shared_key_len desired size of the shared key in bytes - * @param rng the RNG to use - * @param salt a salt value used in the KDF - */ - template - void encrypt(secure_vector& out_encapsulated_key, - secure_vector& out_shared_key, - size_t desired_shared_key_len, - Botan::RandomNumberGenerator& rng, - const std::vector& salt) - { - this->encrypt(out_encapsulated_key, - out_shared_key, - desired_shared_key_len, - rng, - salt.data(), salt.size()); - } + /** + * Generate a shared key for data encryption. + * @param out_encapsulated_key the generated encapsulated key + * @param out_shared_key the generated shared key + * @param desired_shared_key_len desired size of the shared key in bytes + * @param rng the RNG to use + * @param salt a salt value used in the KDF + */ + template + void encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, const std::vector& salt) { + this->encrypt(out_encapsulated_key, out_shared_key, desired_shared_key_len, rng, + salt.data(), salt.size()); + } - - /** - * Generate a shared key for data encryption. - * @param out_encapsulated_key the generated encapsulated key - * @param out_shared_key the generated shared key - * @param desired_shared_key_len desired size of the shared key in bytes - * @param rng the RNG to use - */ - void encrypt(secure_vector& out_encapsulated_key, - secure_vector& out_shared_key, - size_t desired_shared_key_len, - Botan::RandomNumberGenerator& rng) - { - this->encrypt(out_encapsulated_key, - out_shared_key, - desired_shared_key_len, - rng, - nullptr, - 0); - } + /** + * Generate a shared key for data encryption. + * @param out_encapsulated_key the generated encapsulated key + * @param out_shared_key the generated shared key + * @param desired_shared_key_len desired size of the shared key in bytes + * @param rng the RNG to use + */ + void encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng) { + this->encrypt(out_encapsulated_key, out_shared_key, desired_shared_key_len, rng, nullptr, + 0); + } private: - std::unique_ptr m_op; - }; + std::unique_ptr m_op; +}; /** -* Public Key Key Encapsulation Mechanism Decryption. -*/ -class BOTAN_PUBLIC_API(2,0) PK_KEM_Decryptor final - { + * Public Key Key Encapsulation Mechanism Decryption. + */ +class BOTAN_PUBLIC_API(2, 0) PK_KEM_Decryptor final { public: - /** - * Construct an instance. - * @param key the key to use inside the decryptor - * @param rng the RNG to use - * @param kem_param additional KEM parameters - * @param provider the provider to use - */ - PK_KEM_Decryptor(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& kem_param = "", - const std::string& provider = ""); + /** + * Construct an instance. + * @param key the key to use inside the decryptor + * @param rng the RNG to use + * @param kem_param additional KEM parameters + * @param provider the provider to use + */ + PK_KEM_Decryptor(const Private_Key& key, RandomNumberGenerator& rng, + const std::string& kem_param = "", const std::string& provider = ""); #if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) - BOTAN_DEPRECATED("Use constructor taking a RNG object") - PK_KEM_Decryptor(const Private_Key& key, - const std::string& kem_param = "", - const std::string& provider = "") : - PK_KEM_Decryptor(key, system_rng(), kem_param, provider) - {} + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_KEM_Decryptor(const Private_Key& key, const std::string& kem_param = "", + const std::string& provider = "") + : PK_KEM_Decryptor(key, system_rng(), kem_param, provider) {} #endif - ~PK_KEM_Decryptor(); - PK_KEM_Decryptor& operator=(const PK_KEM_Decryptor&) = delete; - PK_KEM_Decryptor(const PK_KEM_Decryptor&) = delete; + ~PK_KEM_Decryptor(); + PK_KEM_Decryptor& operator=(const PK_KEM_Decryptor&) = delete; + PK_KEM_Decryptor(const PK_KEM_Decryptor&) = delete; - /** - * Decrypts the shared key for data encryption. - * @param encap_key the encapsulated key - * @param encap_key_len size of the encapsulated key in bytes - * @param desired_shared_key_len desired size of the shared key in bytes - * @param salt a salt value used in the KDF - * @param salt_len size of the salt value in bytes - * @return the shared data encryption key - */ - secure_vector decrypt(const uint8_t encap_key[], - size_t encap_key_len, - size_t desired_shared_key_len, - const uint8_t salt[], - size_t salt_len); + /** + * Decrypts the shared key for data encryption. + * @param encap_key the encapsulated key + * @param encap_key_len size of the encapsulated key in bytes + * @param desired_shared_key_len desired size of the shared key in bytes + * @param salt a salt value used in the KDF + * @param salt_len size of the salt value in bytes + * @return the shared data encryption key + */ + secure_vector decrypt(const uint8_t encap_key[], size_t encap_key_len, + size_t desired_shared_key_len, const uint8_t salt[], + size_t salt_len); - /** - * Decrypts the shared key for data encryption. - * @param encap_key the encapsulated key - * @param encap_key_len size of the encapsulated key in bytes - * @param desired_shared_key_len desired size of the shared key in bytes - * @return the shared data encryption key - */ - secure_vector decrypt(const uint8_t encap_key[], - size_t encap_key_len, - size_t desired_shared_key_len) - { - return this->decrypt(encap_key, encap_key_len, - desired_shared_key_len, - nullptr, 0); - } + /** + * Decrypts the shared key for data encryption. + * @param encap_key the encapsulated key + * @param encap_key_len size of the encapsulated key in bytes + * @param desired_shared_key_len desired size of the shared key in bytes + * @return the shared data encryption key + */ + secure_vector decrypt(const uint8_t encap_key[], size_t encap_key_len, + size_t desired_shared_key_len) { + return this->decrypt(encap_key, encap_key_len, desired_shared_key_len, nullptr, 0); + } - /** - * Decrypts the shared key for data encryption. - * @param encap_key the encapsulated key - * @param desired_shared_key_len desired size of the shared key in bytes - * @param salt a salt value used in the KDF - * @return the shared data encryption key - */ - template - secure_vector decrypt(const std::vector& encap_key, - size_t desired_shared_key_len, - const std::vector& salt) - { - return this->decrypt(encap_key.data(), encap_key.size(), - desired_shared_key_len, - salt.data(), salt.size()); - } + /** + * Decrypts the shared key for data encryption. + * @param encap_key the encapsulated key + * @param desired_shared_key_len desired size of the shared key in bytes + * @param salt a salt value used in the KDF + * @return the shared data encryption key + */ + template + secure_vector decrypt(const std::vector& encap_key, + size_t desired_shared_key_len, + const std::vector& salt) { + return this->decrypt(encap_key.data(), encap_key.size(), desired_shared_key_len, + salt.data(), salt.size()); + } private: - std::unique_ptr m_op; - }; + std::unique_ptr m_op; +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(rotate.h) +// BOTAN_FUTURE_INTERNAL_HEADER(rotate.h) namespace Botan { /** -* Bit rotation left by a compile-time constant amount -* @param input the input word -* @return input rotated left by ROT bits -*/ -template -inline constexpr T rotl(T input) - { - static_assert(ROT > 0 && ROT < 8*sizeof(T), "Invalid rotation constant"); - return static_cast((input << ROT) | (input >> (8*sizeof(T) - ROT))); - } + * Bit rotation left by a compile-time constant amount + * @param input the input word + * @return input rotated left by ROT bits + */ +template +inline constexpr T rotl(T input) { + static_assert(ROT > 0 && ROT < 8 * sizeof(T), "Invalid rotation constant"); + return static_cast((input << ROT) | (input >> (8 * sizeof(T) - ROT))); +} /** -* Bit rotation right by a compile-time constant amount -* @param input the input word -* @return input rotated right by ROT bits -*/ -template -inline constexpr T rotr(T input) - { - static_assert(ROT > 0 && ROT < 8*sizeof(T), "Invalid rotation constant"); - return static_cast((input >> ROT) | (input << (8*sizeof(T) - ROT))); - } + * Bit rotation right by a compile-time constant amount + * @param input the input word + * @return input rotated right by ROT bits + */ +template +inline constexpr T rotr(T input) { + static_assert(ROT > 0 && ROT < 8 * sizeof(T), "Invalid rotation constant"); + return static_cast((input >> ROT) | (input << (8 * sizeof(T) - ROT))); +} /** -* Bit rotation left, variable rotation amount -* @param input the input word -* @param rot the number of bits to rotate, must be between 0 and sizeof(T)*8-1 -* @return input rotated left by rot bits -*/ -template -inline T rotl_var(T input, size_t rot) - { - return rot ? static_cast((input << rot) | (input >> (sizeof(T)*8 - rot))) : input; - } + * Bit rotation left, variable rotation amount + * @param input the input word + * @param rot the number of bits to rotate, must be between 0 and sizeof(T)*8-1 + * @return input rotated left by rot bits + */ +template +inline T rotl_var(T input, size_t rot) { + return rot ? static_cast((input << rot) | (input >> (sizeof(T) * 8 - rot))) : input; +} /** -* Bit rotation right, variable rotation amount -* @param input the input word -* @param rot the number of bits to rotate, must be between 0 and sizeof(T)*8-1 -* @return input rotated right by rot bits -*/ -template -inline T rotr_var(T input, size_t rot) - { - return rot ? static_cast((input >> rot) | (input << (sizeof(T)*8 - rot))) : input; - } + * Bit rotation right, variable rotation amount + * @param input the input word + * @param rot the number of bits to rotate, must be between 0 and sizeof(T)*8-1 + * @return input rotated right by rot bits + */ +template +inline T rotr_var(T input, size_t rot) { + return rot ? static_cast((input >> rot) | (input << (sizeof(T) * 8 - rot))) : input; +} #if defined(BOTAN_USE_GCC_INLINE_ASM) #if defined(BOTAN_TARGET_ARCH_IS_X86_64) || defined(BOTAN_TARGET_ARCH_IS_X86_32) -template<> -inline uint32_t rotl_var(uint32_t input, size_t rot) - { - asm("roll %1,%0" : "+r" (input) : "c" (static_cast(rot))); - return input; - } - -template<> -inline uint32_t rotr_var(uint32_t input, size_t rot) - { - asm("rorl %1,%0" : "+r" (input) : "c" (static_cast(rot))); - return input; - } - -#endif - -#endif - - -template -BOTAN_DEPRECATED("Use rotl or rotl_var") -inline T rotate_left(T input, size_t rot) - { - // rotl_var does not reduce - return rotl_var(input, rot % (8 * sizeof(T))); - } - -template -BOTAN_DEPRECATED("Use rotr or rotr_var") -inline T rotate_right(T input, size_t rot) - { - // rotr_var does not reduce - return rotr_var(input, rot % (8 * sizeof(T))); - } - +template <> +inline uint32_t rotl_var(uint32_t input, size_t rot) { + asm("roll %1,%0" : "+r"(input) : "c"(static_cast(rot))); + return input; } -//BOTAN_FUTURE_INTERNAL_HEADER(scan_name.h) +template <> +inline uint32_t rotr_var(uint32_t input, size_t rot) { + asm("rorl %1,%0" : "+r"(input) : "c"(static_cast(rot))); + return input; +} + +#endif + +#endif + +template +BOTAN_DEPRECATED("Use rotl or rotl_var") +inline T rotate_left(T input, size_t rot) { + // rotl_var does not reduce + return rotl_var(input, rot % (8 * sizeof(T))); +} + +template +BOTAN_DEPRECATED("Use rotr or rotr_var") +inline T rotate_right(T input, size_t rot) { + // rotr_var does not reduce + return rotr_var(input, rot % (8 * sizeof(T))); +} + +} // namespace Botan + +// BOTAN_FUTURE_INTERNAL_HEADER(scan_name.h) namespace Botan { @@ -13254,485 +12156,455 @@ namespace Botan { A class encapsulating a SCAN name (similar to JCE conventions) http://www.users.zetnet.co.uk/hopwood/crypto/scan/ */ -class BOTAN_PUBLIC_API(2,0) SCAN_Name final - { +class BOTAN_PUBLIC_API(2, 0) SCAN_Name final { public: - /** - * Create a SCAN_Name - * @param algo_spec A SCAN-format name - */ - explicit SCAN_Name(const char* algo_spec); + /** + * Create a SCAN_Name + * @param algo_spec A SCAN-format name + */ + explicit SCAN_Name(const char* algo_spec); - /** - * Create a SCAN_Name - * @param algo_spec A SCAN-format name - */ - explicit SCAN_Name(std::string algo_spec); + /** + * Create a SCAN_Name + * @param algo_spec A SCAN-format name + */ + explicit SCAN_Name(std::string algo_spec); - /** - * @return original input string - */ - const std::string& to_string() const { return m_orig_algo_spec; } + /** + * @return original input string + */ + const std::string& to_string() const { return m_orig_algo_spec; } - BOTAN_DEPRECATED("Use SCAN_Name::to_string") const std::string& as_string() const - { - return this->to_string(); - } + BOTAN_DEPRECATED("Use SCAN_Name::to_string") const std::string& as_string() const { + return this->to_string(); + } - /** - * @return algorithm name - */ - const std::string& algo_name() const { return m_alg_name; } + /** + * @return algorithm name + */ + const std::string& algo_name() const { return m_alg_name; } - /** - * @return number of arguments - */ - size_t arg_count() const { return m_args.size(); } + /** + * @return number of arguments + */ + size_t arg_count() const { return m_args.size(); } - /** - * @param lower is the lower bound - * @param upper is the upper bound - * @return if the number of arguments is between lower and upper - */ - bool arg_count_between(size_t lower, size_t upper) const - { return ((arg_count() >= lower) && (arg_count() <= upper)); } + /** + * @param lower is the lower bound + * @param upper is the upper bound + * @return if the number of arguments is between lower and upper + */ + bool arg_count_between(size_t lower, size_t upper) const { + return ((arg_count() >= lower) && (arg_count() <= upper)); + } - /** - * @param i which argument - * @return ith argument - */ - std::string arg(size_t i) const; + /** + * @param i which argument + * @return ith argument + */ + std::string arg(size_t i) const; - /** - * @param i which argument - * @param def_value the default value - * @return ith argument or the default value - */ - std::string arg(size_t i, const std::string& def_value) const; + /** + * @param i which argument + * @param def_value the default value + * @return ith argument or the default value + */ + std::string arg(size_t i, const std::string& def_value) const; - /** - * @param i which argument - * @param def_value the default value - * @return ith argument as an integer, or the default value - */ - size_t arg_as_integer(size_t i, size_t def_value) const; + /** + * @param i which argument + * @param def_value the default value + * @return ith argument as an integer, or the default value + */ + size_t arg_as_integer(size_t i, size_t def_value) const; - /** - * @return cipher mode (if any) - */ - std::string cipher_mode() const - { return (m_mode_info.size() >= 1) ? m_mode_info[0] : ""; } + /** + * @return cipher mode (if any) + */ + std::string cipher_mode() const { return (m_mode_info.size() >= 1) ? m_mode_info[0] : ""; } - /** - * @return cipher mode padding (if any) - */ - std::string cipher_mode_pad() const - { return (m_mode_info.size() >= 2) ? m_mode_info[1] : ""; } + /** + * @return cipher mode padding (if any) + */ + std::string cipher_mode_pad() const { return (m_mode_info.size() >= 2) ? m_mode_info[1] : ""; } private: - std::string m_orig_algo_spec; - std::string m_alg_name; - std::vector m_args; - std::vector m_mode_info; - }; + std::string m_orig_algo_spec; + std::string m_alg_name; + std::vector m_args; + std::vector m_mode_info; +}; // This is unrelated but it is convenient to stash it here -template +template std::vector probe_providers_of(const std::string& algo_spec, - const std::vector& possible) - { - std::vector providers; - for(auto&& prov : possible) - { - std::unique_ptr o(T::create(algo_spec, prov)); - if(o) - { - providers.push_back(prov); // available - } - } - return providers; - } - + const std::vector& possible) { + std::vector providers; + for (auto&& prov : possible) { + std::unique_ptr o(T::create(algo_spec, prov)); + if (o) { + providers.push_back(prov); // available + } + } + return providers; } -//BOTAN_FUTURE_INTERNAL_HEADER(secqueue.h) +} // namespace Botan + +// BOTAN_FUTURE_INTERNAL_HEADER(secqueue.h) namespace Botan { /** -* A queue that knows how to zeroize itself -*/ -class BOTAN_PUBLIC_API(2,0) SecureQueue final : public Fanout_Filter, public DataSource - { + * A queue that knows how to zeroize itself + */ +class BOTAN_PUBLIC_API(2, 0) SecureQueue final : public Fanout_Filter, public DataSource { public: - std::string name() const override { return "Queue"; } + std::string name() const override { return "Queue"; } - void write(const uint8_t[], size_t) override; + void write(const uint8_t[], size_t) override; - size_t read(uint8_t[], size_t) override; - size_t peek(uint8_t[], size_t, size_t = 0) const override; - size_t get_bytes_read() const override; + size_t read(uint8_t[], size_t) override; + size_t peek(uint8_t[], size_t, size_t = 0) const override; + size_t get_bytes_read() const override; - bool end_of_data() const override; + bool end_of_data() const override; - bool empty() const; + bool empty() const; - bool check_available(size_t n) override { return n <= size(); } + bool check_available(size_t n) override { return n <= size(); } - /** - * @return number of bytes available in the queue - */ - size_t size() const; + /** + * @return number of bytes available in the queue + */ + size_t size() const; - bool attachable() override { return false; } + bool attachable() override { return false; } - /** - * SecureQueue assignment - * @param other the queue to copy - */ - SecureQueue& operator=(const SecureQueue& other); + /** + * SecureQueue assignment + * @param other the queue to copy + */ + SecureQueue& operator=(const SecureQueue& other); - /** - * SecureQueue default constructor (creates empty queue) - */ - SecureQueue(); + /** + * SecureQueue default constructor (creates empty queue) + */ + SecureQueue(); - /** - * SecureQueue copy constructor - * @param other the queue to copy - */ - SecureQueue(const SecureQueue& other); + /** + * SecureQueue copy constructor + * @param other the queue to copy + */ + SecureQueue(const SecureQueue& other); - ~SecureQueue() { destroy(); } + ~SecureQueue() { destroy(); } private: - void destroy(); - size_t m_bytes_read; - class SecureQueueNode* m_head; - class SecureQueueNode* m_tail; - }; + void destroy(); + size_t m_bytes_read; + class SecureQueueNode* m_head; + class SecureQueueNode* m_tail; +}; -} +} // namespace Botan -//BOTAN_FUTURE_INTERNAL_HEADER(sha160.h) +// BOTAN_FUTURE_INTERNAL_HEADER(sha160.h) namespace Botan { /** -* NIST's SHA-160 -*/ -class BOTAN_PUBLIC_API(2,0) SHA_160 final : public MDx_HashFunction - { + * NIST's SHA-160 + */ +class BOTAN_PUBLIC_API(2, 0) SHA_160 final : public MDx_HashFunction { public: - std::string name() const override { return "SHA-160"; } - size_t output_length() const override { return 20; } - HashFunction* clone() const override { return new SHA_160; } - std::unique_ptr copy_state() const override; + std::string name() const override { return "SHA-160"; } + size_t output_length() const override { return 20; } + HashFunction* clone() const override { return new SHA_160; } + std::unique_ptr copy_state() const override; - void clear() override; + void clear() override; - SHA_160() : MDx_HashFunction(64, true, true), m_digest(5) - { - clear(); - } + SHA_160() : MDx_HashFunction(64, true, true), m_digest(5) { clear(); } private: - void compress_n(const uint8_t[], size_t blocks) override; + void compress_n(const uint8_t[], size_t blocks) override; #if defined(BOTAN_HAS_SHA1_ARMV8) - static void sha1_armv8_compress_n(secure_vector& digest, - const uint8_t blocks[], - size_t block_count); + static void sha1_armv8_compress_n(secure_vector& digest, const uint8_t blocks[], + size_t block_count); #endif #if defined(BOTAN_HAS_SHA1_SSE2) - static void sse2_compress_n(secure_vector& digest, - const uint8_t blocks[], - size_t block_count); + static void sse2_compress_n(secure_vector& digest, const uint8_t blocks[], + size_t block_count); #endif #if defined(BOTAN_HAS_SHA1_X86_SHA_NI) - // Using x86 SHA instructions in Intel Goldmont and Cannonlake - static void sha1_compress_x86(secure_vector& digest, - const uint8_t blocks[], - size_t block_count); + // Using x86 SHA instructions in Intel Goldmont and Cannonlake + static void sha1_compress_x86(secure_vector& digest, const uint8_t blocks[], + size_t block_count); #endif + void copy_out(uint8_t[]) override; - void copy_out(uint8_t[]) override; + /** + * The digest value + */ + secure_vector m_digest; - /** - * The digest value - */ - secure_vector m_digest; - - /** - * The message buffer - */ - secure_vector m_W; - }; + /** + * The message buffer + */ + secure_vector m_W; +}; typedef SHA_160 SHA_1; -} +} // namespace Botan #if __cplusplus < 201402L #endif -//BOTAN_FUTURE_INTERNAL_HEADER(stl_compatability.h) +// BOTAN_FUTURE_INTERNAL_HEADER(stl_compatability.h) -namespace Botan -{ +namespace Botan { /* -* std::make_unique functionality similar as we have in C++14. -* C++11 version based on proposal for C++14 implemenatation by Stephan T. Lavavej -* source: https://isocpp.org/files/papers/N3656.txt -*/ + * std::make_unique functionality similar as we have in C++14. + * C++11 version based on proposal for C++14 implemenatation by Stephan T. Lavavej + * source: https://isocpp.org/files/papers/N3656.txt + */ #if __cplusplus >= 201402L -template -constexpr auto make_unique(Args&&... args) - { - return std::make_unique(std::forward(args)...); - } +template +constexpr auto make_unique(Args&&... args) { + return std::make_unique(std::forward(args)...); +} -template -constexpr auto make_unique(std::size_t size) - { - return std::make_unique(size); - } +template +constexpr auto make_unique(std::size_t size) { + return std::make_unique(size); +} #else -namespace stlCompatibilityDetails -{ -template struct _Unique_if - { - typedef std::unique_ptr _Single_object; - }; +namespace stlCompatibilityDetails { +template +struct _Unique_if { + typedef std::unique_ptr _Single_object; +}; -template struct _Unique_if - { - typedef std::unique_ptr _Unknown_bound; - }; +template +struct _Unique_if { + typedef std::unique_ptr _Unknown_bound; +}; -template struct _Unique_if - { - typedef void _Known_bound; - }; -} // namespace stlCompatibilityDetails +template +struct _Unique_if { + typedef void _Known_bound; +}; +} // namespace stlCompatibilityDetails -template -typename stlCompatibilityDetails::_Unique_if::_Single_object make_unique(Args&&... args) - { - return std::unique_ptr(new T(std::forward(args)...)); - } +template +typename stlCompatibilityDetails::_Unique_if::_Single_object make_unique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} -template -typename stlCompatibilityDetails::_Unique_if::_Unknown_bound make_unique(size_t n) - { - typedef typename std::remove_extent::type U; - return std::unique_ptr(new U[n]()); - } +template +typename stlCompatibilityDetails::_Unique_if::_Unknown_bound make_unique(size_t n) { + typedef typename std::remove_extent::type U; + return std::unique_ptr(new U[n]()); +} -template +template typename stlCompatibilityDetails::_Unique_if::_Known_bound make_unique(Args&&...) = delete; #endif -} // namespace Botan +} // namespace Botan #if defined(BOTAN_HAS_STREAM_CIPHER) #endif -//BOTAN_FUTURE_INTERNAL_HEADER(stream_mode.h) +// BOTAN_FUTURE_INTERNAL_HEADER(stream_mode.h) namespace Botan { #if defined(BOTAN_HAS_STREAM_CIPHER) -class BOTAN_PUBLIC_API(2,0) Stream_Cipher_Mode final : public Cipher_Mode - { +class BOTAN_PUBLIC_API(2, 0) Stream_Cipher_Mode final : public Cipher_Mode { public: - /** - * @param cipher underyling stream cipher - */ - explicit Stream_Cipher_Mode(StreamCipher* cipher) : m_cipher(cipher) {} + /** + * @param cipher underyling stream cipher + */ + explicit Stream_Cipher_Mode(StreamCipher* cipher) : m_cipher(cipher) {} - size_t process(uint8_t buf[], size_t sz) override - { - m_cipher->cipher1(buf, sz); - return sz; - } + size_t process(uint8_t buf[], size_t sz) override { + m_cipher->cipher1(buf, sz); + return sz; + } - void finish(secure_vector& buf, size_t offset) override - { return update(buf, offset); } + void finish(secure_vector& buf, size_t offset) override { return update(buf, offset); } - size_t output_length(size_t input_length) const override { return input_length; } + size_t output_length(size_t input_length) const override { return input_length; } - size_t update_granularity() const override { return 1; } + size_t update_granularity() const override { return 1; } - size_t minimum_final_size() const override { return 0; } + size_t minimum_final_size() const override { return 0; } - size_t default_nonce_length() const override { return 0; } + size_t default_nonce_length() const override { return 0; } - bool valid_nonce_length(size_t nonce_len) const override - { return m_cipher->valid_iv_length(nonce_len); } + bool valid_nonce_length(size_t nonce_len) const override { + return m_cipher->valid_iv_length(nonce_len); + } - Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } + Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } - std::string name() const override { return m_cipher->name(); } + std::string name() const override { return m_cipher->name(); } - void clear() override - { - m_cipher->clear(); - reset(); - } + void clear() override { + m_cipher->clear(); + reset(); + } - void reset() override { /* no msg state */ } + void reset() override { /* no msg state */ } private: - void start_msg(const uint8_t nonce[], size_t nonce_len) override - { - if(nonce_len > 0) - { + void start_msg(const uint8_t nonce[], size_t nonce_len) override { + if (nonce_len > 0) { m_cipher->set_iv(nonce, nonce_len); - } - } + } + } - void key_schedule(const uint8_t key[], size_t length) override - { - m_cipher->set_key(key, length); - } + void key_schedule(const uint8_t key[], size_t length) override { + m_cipher->set_key(key, length); + } - std::unique_ptr m_cipher; - }; + std::unique_ptr m_cipher; +}; #endif -} +} // namespace Botan namespace Botan { /* -* Get information describing the version -*/ + * Get information describing the version + */ /** -* Get a human-readable string identifying the version of Botan. -* No particular format should be assumed. -* @return version string -*/ -BOTAN_PUBLIC_API(2,0) std::string version_string(); + * Get a human-readable string identifying the version of Botan. + * No particular format should be assumed. + * @return version string + */ +BOTAN_PUBLIC_API(2, 0) std::string version_string(); /** -* Same as version_string() except returning a pointer to a statically -* allocated string. -* @return version string -*/ -BOTAN_PUBLIC_API(2,0) const char* version_cstr(); + * Same as version_string() except returning a pointer to a statically + * allocated string. + * @return version string + */ +BOTAN_PUBLIC_API(2, 0) const char* version_cstr(); /** -* Return a version string of the form "MAJOR.MINOR.PATCH" where -* each of the values is an integer. -*/ -BOTAN_PUBLIC_API(2,4) std::string short_version_string(); + * Return a version string of the form "MAJOR.MINOR.PATCH" where + * each of the values is an integer. + */ +BOTAN_PUBLIC_API(2, 4) std::string short_version_string(); /** -* Same as version_short_string except returning a pointer to the string. -*/ -BOTAN_PUBLIC_API(2,4) const char* short_version_cstr(); + * Same as version_short_string except returning a pointer to the string. + */ +BOTAN_PUBLIC_API(2, 4) const char* short_version_cstr(); /** -* Return the date this version of botan was released, in an integer of -* the form YYYYMMDD. For instance a version released on May 21, 2013 -* would return the integer 20130521. If the currently running version -* is not an official release, this function will return 0 instead. -* -* @return release date, or zero if unreleased -*/ -BOTAN_PUBLIC_API(2,0) uint32_t version_datestamp(); + * Return the date this version of botan was released, in an integer of + * the form YYYYMMDD. For instance a version released on May 21, 2013 + * would return the integer 20130521. If the currently running version + * is not an official release, this function will return 0 instead. + * + * @return release date, or zero if unreleased + */ +BOTAN_PUBLIC_API(2, 0) uint32_t version_datestamp(); /** -* Get the major version number. -* @return major version number -*/ -BOTAN_PUBLIC_API(2,0) uint32_t version_major(); + * Get the major version number. + * @return major version number + */ +BOTAN_PUBLIC_API(2, 0) uint32_t version_major(); /** -* Get the minor version number. -* @return minor version number -*/ -BOTAN_PUBLIC_API(2,0) uint32_t version_minor(); + * Get the minor version number. + * @return minor version number + */ +BOTAN_PUBLIC_API(2, 0) uint32_t version_minor(); /** -* Get the patch number. -* @return patch number -*/ -BOTAN_PUBLIC_API(2,0) uint32_t version_patch(); + * Get the patch number. + * @return patch number + */ +BOTAN_PUBLIC_API(2, 0) uint32_t version_patch(); /** -* Usable for checking that the DLL version loaded at runtime exactly -* matches the compile-time version. Call using BOTAN_VERSION_* macro -* values. Returns the empty string if an exact match, otherwise an -* appropriate message. Added with 1.11.26. -*/ -BOTAN_PUBLIC_API(2,0) std::string -runtime_version_check(uint32_t major, - uint32_t minor, - uint32_t patch); + * Usable for checking that the DLL version loaded at runtime exactly + * matches the compile-time version. Call using BOTAN_VERSION_* macro + * values. Returns the empty string if an exact match, otherwise an + * appropriate message. Added with 1.11.26. + */ +BOTAN_PUBLIC_API(2, 0) +std::string runtime_version_check(uint32_t major, uint32_t minor, uint32_t patch); /* -* Macros for compile-time version checks -*/ -#define BOTAN_VERSION_CODE_FOR(a,b,c) ((a << 16) | (b << 8) | (c)) + * Macros for compile-time version checks + */ +#define BOTAN_VERSION_CODE_FOR(a, b, c) ((a << 16) | (b << 8) | (c)) /** -* Compare using BOTAN_VERSION_CODE_FOR, as in -* # if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,8,0) -* # error "Botan version too old" -* # endif -*/ -#define BOTAN_VERSION_CODE BOTAN_VERSION_CODE_FOR(BOTAN_VERSION_MAJOR, \ - BOTAN_VERSION_MINOR, \ - BOTAN_VERSION_PATCH) + * Compare using BOTAN_VERSION_CODE_FOR, as in + * # if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,8,0) + * # error "Botan version too old" + * # endif + */ +#define BOTAN_VERSION_CODE \ + BOTAN_VERSION_CODE_FOR(BOTAN_VERSION_MAJOR, BOTAN_VERSION_MINOR, BOTAN_VERSION_PATCH) -} +} // namespace Botan namespace Botan { /** -* Estimate work factor for discrete logarithm -* @param prime_group_size size of the group in bits -* @return estimated security level for this group -*/ -BOTAN_PUBLIC_API(2,0) size_t dl_work_factor(size_t prime_group_size); + * Estimate work factor for discrete logarithm + * @param prime_group_size size of the group in bits + * @return estimated security level for this group + */ +BOTAN_PUBLIC_API(2, 0) size_t dl_work_factor(size_t prime_group_size); /** -* Return the appropriate exponent size to use for a particular prime -* group. This is twice the size of the estimated cost of breaking the -* key using an index calculus attack; the assumption is that if an -* arbitrary discrete log on a group of size bits would take about 2^n -* effort, and thus using an exponent of size 2^(2*n) implies that all -* available attacks are about as easy (as e.g Pollard's kangaroo -* algorithm can compute the DL in sqrt(x) operations) while minimizing -* the exponent size for performance reasons. -*/ -BOTAN_PUBLIC_API(2,0) size_t dl_exponent_size(size_t prime_group_size); + * Return the appropriate exponent size to use for a particular prime + * group. This is twice the size of the estimated cost of breaking the + * key using an index calculus attack; the assumption is that if an + * arbitrary discrete log on a group of size bits would take about 2^n + * effort, and thus using an exponent of size 2^(2*n) implies that all + * available attacks are about as easy (as e.g Pollard's kangaroo + * algorithm can compute the DL in sqrt(x) operations) while minimizing + * the exponent size for performance reasons. + */ +BOTAN_PUBLIC_API(2, 0) size_t dl_exponent_size(size_t prime_group_size); /** -* Estimate work factor for integer factorization -* @param n_bits size of modulus in bits -* @return estimated security level for this modulus -*/ -BOTAN_PUBLIC_API(2,0) size_t if_work_factor(size_t n_bits); + * Estimate work factor for integer factorization + * @param n_bits size of modulus in bits + * @return estimated security level for this modulus + */ +BOTAN_PUBLIC_API(2, 0) size_t if_work_factor(size_t n_bits); /** -* Estimate work factor for EC discrete logarithm -* @param prime_group_size size of the group in bits -* @return estimated security level for this group -*/ -BOTAN_PUBLIC_API(2,0) size_t ecp_work_factor(size_t prime_group_size); + * Estimate work factor for EC discrete logarithm + * @param prime_group_size size of the group in bits + * @return estimated security level for this group + */ +BOTAN_PUBLIC_API(2, 0) size_t ecp_work_factor(size_t prime_group_size); -} +} // namespace Botan namespace Botan { @@ -13740,62 +12612,62 @@ class RandomNumberGenerator; class DataSource; /** -* The two types of X509 encoding supported by Botan. -* This enum is not used anymore, and will be removed in a future major release. -*/ + * The two types of X509 encoding supported by Botan. + * This enum is not used anymore, and will be removed in a future major release. + */ enum X509_Encoding { RAW_BER, PEM }; /** -* This namespace contains functions for handling X.509 public keys -*/ + * This namespace contains functions for handling X.509 public keys + */ namespace X509 { /** -* BER encode a key -* @param key the public key to encode -* @return BER encoding of this key -*/ -BOTAN_PUBLIC_API(2,0) std::vector BER_encode(const Public_Key& key); + * BER encode a key + * @param key the public key to encode + * @return BER encoding of this key + */ +BOTAN_PUBLIC_API(2, 0) std::vector BER_encode(const Public_Key& key); /** -* PEM encode a public key into a string. -* @param key the key to encode -* @return PEM encoded key -*/ -BOTAN_PUBLIC_API(2,0) std::string PEM_encode(const Public_Key& key); + * PEM encode a public key into a string. + * @param key the key to encode + * @return PEM encoded key + */ +BOTAN_PUBLIC_API(2, 0) std::string PEM_encode(const Public_Key& key); /** -* Create a public key from a data source. -* @param source the source providing the DER or PEM encoded key -* @return new public key object -*/ -BOTAN_PUBLIC_API(2,0) Public_Key* load_key(DataSource& source); + * Create a public key from a data source. + * @param source the source providing the DER or PEM encoded key + * @return new public key object + */ +BOTAN_PUBLIC_API(2, 0) Public_Key* load_key(DataSource& source); #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) /** -* Create a public key from a file -* @param filename pathname to the file to load -* @return new public key object -*/ -BOTAN_PUBLIC_API(2,0) Public_Key* load_key(const std::string& filename); + * Create a public key from a file + * @param filename pathname to the file to load + * @return new public key object + */ +BOTAN_PUBLIC_API(2, 0) Public_Key* load_key(const std::string& filename); #endif /** -* Create a public key from a memory region. -* @param enc the memory region containing the DER or PEM encoded key -* @return new public key object -*/ -BOTAN_PUBLIC_API(2,0) Public_Key* load_key(const std::vector& enc); + * Create a public key from a memory region. + * @param enc the memory region containing the DER or PEM encoded key + * @return new public key object + */ +BOTAN_PUBLIC_API(2, 0) Public_Key* load_key(const std::vector& enc); /** -* Copy a key. -* @param key the public key to copy -* @return new public key object -*/ -BOTAN_PUBLIC_API(2,0) Public_Key* copy_key(const Public_Key& key); + * Copy a key. + * @param key the public key to copy + * @return new public key object + */ +BOTAN_PUBLIC_API(2, 0) Public_Key* copy_key(const Public_Key& key); -} +} // namespace X509 -} +} // namespace Botan -#endif // BOTAN_AMALGAMATION_H_ +#endif // BOTAN_AMALGAMATION_H_ diff --git a/src/libraries/botan/botan_internal.h b/src/libraries/botan/botan_internal.h index dd7836671..62bfe2754 100644 --- a/src/libraries/botan/botan_internal.h +++ b/src/libraries/botan/botan_internal.h @@ -1,9 +1,9 @@ /* -* Botan 2.12.0 Amalgamation -* (C) 1999-2018 The Botan Authors -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ + * Botan 2.12.0 Amalgamation + * (C) 1999-2018 The Botan Authors + * + * Botan is released under the Simplified BSD License (see license.txt) + */ #ifndef BOTAN_AMALGAMATION_INTERNAL_H_ #define BOTAN_AMALGAMATION_INTERNAL_H_ @@ -19,140 +19,125 @@ #include #include - namespace Botan { /** -* If top bit of arg is set, return ~0. Otherwise return 0. -*/ -template -inline T expand_top_bit(T a) - { - return static_cast(0) - (a >> (sizeof(T)*8-1)); - } + * If top bit of arg is set, return ~0. Otherwise return 0. + */ +template +inline T expand_top_bit(T a) { + return static_cast(0) - (a >> (sizeof(T) * 8 - 1)); +} /** -* If arg is zero, return ~0. Otherwise return 0 -*/ -template -inline T ct_is_zero(T x) - { - return expand_top_bit(~x & (x - 1)); - } + * If arg is zero, return ~0. Otherwise return 0 + */ +template +inline T ct_is_zero(T x) { + return expand_top_bit(~x & (x - 1)); +} /** -* Power of 2 test. T should be an unsigned integer type -* @param arg an integer value -* @return true iff arg is 2^n for some n > 0 -*/ -template -inline constexpr bool is_power_of_2(T arg) - { - return (arg != 0) && (arg != 1) && ((arg & static_cast(arg-1)) == 0); - } + * Power of 2 test. T should be an unsigned integer type + * @param arg an integer value + * @return true iff arg is 2^n for some n > 0 + */ +template +inline constexpr bool is_power_of_2(T arg) { + return (arg != 0) && (arg != 1) && ((arg & static_cast(arg - 1)) == 0); +} /** -* Return the index of the highest set bit -* T is an unsigned integer type -* @param n an integer value -* @return index of the highest set bit in n -*/ -template -inline size_t high_bit(T n) - { - size_t hb = 0; + * Return the index of the highest set bit + * T is an unsigned integer type + * @param n an integer value + * @return index of the highest set bit in n + */ +template +inline size_t high_bit(T n) { + size_t hb = 0; - for(size_t s = 8*sizeof(T) / 2; s > 0; s /= 2) - { - const size_t z = s * ((~ct_is_zero(n >> s)) & 1); - hb += z; - n >>= z; - } + for (size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) { + const size_t z = s * ((~ct_is_zero(n >> s)) & 1); + hb += z; + n >>= z; + } - hb += n; + hb += n; - return hb; - } + return hb; +} /** -* Return the number of significant bytes in n -* @param n an integer value -* @return number of significant bytes in n -*/ -template -inline size_t significant_bytes(T n) - { - size_t b = 0; + * Return the number of significant bytes in n + * @param n an integer value + * @return number of significant bytes in n + */ +template +inline size_t significant_bytes(T n) { + size_t b = 0; - for(size_t s = 8*sizeof(n) / 2; s >= 8; s /= 2) - { - const size_t z = s * (~ct_is_zero(n >> s) & 1); - b += z/8; - n >>= z; - } + for (size_t s = 8 * sizeof(n) / 2; s >= 8; s /= 2) { + const size_t z = s * (~ct_is_zero(n >> s) & 1); + b += z / 8; + n >>= z; + } - b += (n != 0); + b += (n != 0); - return b; - } + return b; +} /** -* Count the trailing zero bits in n -* @param n an integer value -* @return maximum x st 2^x divides n -*/ -template -inline size_t ctz(T n) - { - /* - * If n == 0 then this function will compute 8*sizeof(T)-1, so - * initialize lb to 1 if n == 0 to produce the expected result. - */ - size_t lb = ct_is_zero(n) & 1; + * Count the trailing zero bits in n + * @param n an integer value + * @return maximum x st 2^x divides n + */ +template +inline size_t ctz(T n) { + /* + * If n == 0 then this function will compute 8*sizeof(T)-1, so + * initialize lb to 1 if n == 0 to produce the expected result. + */ + size_t lb = ct_is_zero(n) & 1; - for(size_t s = 8*sizeof(T) / 2; s > 0; s /= 2) - { - const T mask = (static_cast(1) << s) - 1; - const size_t z = s * (ct_is_zero(n & mask) & 1); - lb += z; - n >>= z; - } + for (size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) { + const T mask = (static_cast(1) << s) - 1; + const size_t z = s * (ct_is_zero(n & mask) & 1); + lb += z; + n >>= z; + } - return lb; - } + return lb; +} -template -size_t ceil_log2(T x) - { - if(x >> (sizeof(T)*8-1)) - return sizeof(T)*8; +template +size_t ceil_log2(T x) { + if (x >> (sizeof(T) * 8 - 1)) return sizeof(T) * 8; - size_t result = 0; - T compare = 1; + size_t result = 0; + T compare = 1; - while(compare < x) - { - compare <<= 1; - result++; - } + while (compare < x) { + compare <<= 1; + result++; + } - return result; - } + return result; +} // Potentially variable time ctz used for OCB -inline size_t var_ctz32(uint32_t n) - { +inline size_t var_ctz32(uint32_t n) { #if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) - if(n == 0) - return 32; - return __builtin_ctz(n); + if (n == 0) return 32; + return __builtin_ctz(n); #else - return ctz(n); + return ctz(n); #endif - } - } +} // namespace Botan + namespace Botan { /** @@ -170,78 +155,66 @@ namespace Botan { * @return number of bytes written to output */ template -size_t base_encode(Base&& base, - char output[], - const uint8_t input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs) - { - input_consumed = 0; +size_t base_encode(Base&& base, char output[], const uint8_t input[], size_t input_length, + size_t& input_consumed, bool final_inputs) { + input_consumed = 0; - const size_t encoding_bytes_in = base.encoding_bytes_in(); - const size_t encoding_bytes_out = base.encoding_bytes_out(); + const size_t encoding_bytes_in = base.encoding_bytes_in(); + const size_t encoding_bytes_out = base.encoding_bytes_out(); - size_t input_remaining = input_length; - size_t output_produced = 0; + size_t input_remaining = input_length; + size_t output_produced = 0; - while(input_remaining >= encoding_bytes_in) - { - base.encode(output + output_produced, input + input_consumed); + while (input_remaining >= encoding_bytes_in) { + base.encode(output + output_produced, input + input_consumed); - input_consumed += encoding_bytes_in; - output_produced += encoding_bytes_out; - input_remaining -= encoding_bytes_in; - } + input_consumed += encoding_bytes_in; + output_produced += encoding_bytes_out; + input_remaining -= encoding_bytes_in; + } - if(final_inputs && input_remaining) - { - std::vector remainder(encoding_bytes_in, 0); - for(size_t i = 0; i != input_remaining; ++i) - { remainder[i] = input[input_consumed + i]; } + if (final_inputs && input_remaining) { + std::vector remainder(encoding_bytes_in, 0); + for (size_t i = 0; i != input_remaining; ++i) { + remainder[i] = input[input_consumed + i]; + } - base.encode(output + output_produced, remainder.data()); + base.encode(output + output_produced, remainder.data()); - const size_t bits_consumed = base.bits_consumed(); - const size_t remaining_bits_before_padding = base.remaining_bits_before_padding(); + const size_t bits_consumed = base.bits_consumed(); + const size_t remaining_bits_before_padding = base.remaining_bits_before_padding(); - size_t empty_bits = 8 * (encoding_bytes_in - input_remaining); - size_t index = output_produced + encoding_bytes_out - 1; - while(empty_bits >= remaining_bits_before_padding) - { - output[index--] = '='; - empty_bits -= bits_consumed; - } + size_t empty_bits = 8 * (encoding_bytes_in - input_remaining); + size_t index = output_produced + encoding_bytes_out - 1; + while (empty_bits >= remaining_bits_before_padding) { + output[index--] = '='; + empty_bits -= bits_consumed; + } - input_consumed += input_remaining; - output_produced += encoding_bytes_out; - } - - return output_produced; - } + input_consumed += input_remaining; + output_produced += encoding_bytes_out; + } + return output_produced; +} template -std::string base_encode_to_string(Base&& base, const uint8_t input[], size_t input_length) - { - const size_t output_length = base.encode_max_output(input_length); - std::string output(output_length, 0); +std::string base_encode_to_string(Base&& base, const uint8_t input[], size_t input_length) { + const size_t output_length = base.encode_max_output(input_length); + std::string output(output_length, 0); - size_t consumed = 0; - size_t produced = 0; + size_t consumed = 0; + size_t produced = 0; - if(output_length > 0) - { - produced = base_encode(base, &output.front(), - input, input_length, - consumed, true); - } + if (output_length > 0) { + produced = base_encode(base, &output.front(), input, input_length, consumed, true); + } - BOTAN_ASSERT_EQUAL(consumed, input_length, "Consumed the entire input"); - BOTAN_ASSERT_EQUAL(produced, output.size(), "Produced expected size"); + BOTAN_ASSERT_EQUAL(consumed, input_length, "Consumed the entire input"); + BOTAN_ASSERT_EQUAL(produced, output.size(), "Produced expected size"); - return output; - } + return output; +} /** * Perform decoding using the base provided @@ -260,104 +233,89 @@ std::string base_encode_to_string(Base&& base, const uint8_t input[], size_t inp * @return number of bytes written to output */ template -size_t base_decode(Base&& base, - uint8_t output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs, - bool ignore_ws = true) - { - const size_t decoding_bytes_in = base.decoding_bytes_in(); - const size_t decoding_bytes_out = base.decoding_bytes_out(); +size_t base_decode(Base&& base, uint8_t output[], const char input[], size_t input_length, + size_t& input_consumed, bool final_inputs, bool ignore_ws = true) { + const size_t decoding_bytes_in = base.decoding_bytes_in(); + const size_t decoding_bytes_out = base.decoding_bytes_out(); - uint8_t* out_ptr = output; - std::vector decode_buf(decoding_bytes_in, 0); - size_t decode_buf_pos = 0; - size_t final_truncate = 0; + uint8_t* out_ptr = output; + std::vector decode_buf(decoding_bytes_in, 0); + size_t decode_buf_pos = 0; + size_t final_truncate = 0; - clear_mem(output, base.decode_max_output(input_length)); + clear_mem(output, base.decode_max_output(input_length)); - for(size_t i = 0; i != input_length; ++i) - { - const uint8_t bin = base.lookup_binary_value(input[i]); + for (size_t i = 0; i != input_length; ++i) { + const uint8_t bin = base.lookup_binary_value(input[i]); - if(base.check_bad_char(bin, input[i], ignore_ws)) // May throw Invalid_Argument - { - decode_buf[decode_buf_pos] = bin; - ++decode_buf_pos; - } + if (base.check_bad_char(bin, input[i], ignore_ws)) // May throw Invalid_Argument + { + decode_buf[decode_buf_pos] = bin; + ++decode_buf_pos; + } - /* - * If we're at the end of the input, pad with 0s and truncate - */ - if(final_inputs && (i == input_length - 1)) - { - if(decode_buf_pos) - { - for(size_t j = decode_buf_pos; j < decoding_bytes_in; ++j) - { decode_buf[j] = 0; } + /* + * If we're at the end of the input, pad with 0s and truncate + */ + if (final_inputs && (i == input_length - 1)) { + if (decode_buf_pos) { + for (size_t j = decode_buf_pos; j < decoding_bytes_in; ++j) { + decode_buf[j] = 0; + } - final_truncate = decoding_bytes_in - decode_buf_pos; - decode_buf_pos = decoding_bytes_in; + final_truncate = decoding_bytes_in - decode_buf_pos; + decode_buf_pos = decoding_bytes_in; } - } + } - if(decode_buf_pos == decoding_bytes_in) - { - base.decode(out_ptr, decode_buf.data()); + if (decode_buf_pos == decoding_bytes_in) { + base.decode(out_ptr, decode_buf.data()); - out_ptr += decoding_bytes_out; - decode_buf_pos = 0; - input_consumed = i+1; - } - } + out_ptr += decoding_bytes_out; + decode_buf_pos = 0; + input_consumed = i + 1; + } + } - while(input_consumed < input_length && - base.lookup_binary_value(input[input_consumed]) == 0x80) - { - ++input_consumed; - } + while (input_consumed < input_length && + base.lookup_binary_value(input[input_consumed]) == 0x80) { + ++input_consumed; + } - size_t written = (out_ptr - output) - base.bytes_to_remove(final_truncate); - - return written; - } - -template -size_t base_decode_full(Base&& base, uint8_t output[], const char input[], size_t input_length, bool ignore_ws) - { - size_t consumed = 0; - const size_t written = base_decode(base, output, input, input_length, consumed, true, ignore_ws); - - if(consumed != input_length) - { - throw Invalid_Argument(base.name() + " decoding failed, input did not have full bytes"); - } - - return written; - } - -template -Vector base_decode_to_vec(Base&& base, - const char input[], - size_t input_length, - bool ignore_ws) - { - const size_t output_length = base.decode_max_output(input_length); - Vector bin(output_length); - - const size_t written = - base_decode_full(base, bin.data(), input, input_length, ignore_ws); - - bin.resize(written); - return bin; - } + size_t written = (out_ptr - output) - base.bytes_to_remove(final_truncate); + return written; } +template +size_t base_decode_full(Base&& base, uint8_t output[], const char input[], size_t input_length, + bool ignore_ws) { + size_t consumed = 0; + const size_t written = + base_decode(base, output, input, input_length, consumed, true, ignore_ws); + + if (consumed != input_length) { + throw Invalid_Argument(base.name() + " decoding failed, input did not have full bytes"); + } + + return written; +} + +template +Vector base_decode_to_vec(Base&& base, const char input[], size_t input_length, bool ignore_ws) { + const size_t output_length = base.decode_max_output(input_length); + Vector bin(output_length); + + const size_t written = base_decode_full(base, bin.data(), input, input_length, ignore_ws); + + bin.resize(written); + return bin; +} + +} // namespace Botan + #if defined(BOTAN_HAS_VALGRIND) - #include +#include #endif namespace Botan { @@ -365,516 +323,416 @@ namespace Botan { namespace CT { /** -* Use valgrind to mark the contents of memory as being undefined. -* Valgrind will accept operations which manipulate undefined values, -* but will warn if an undefined value is used to decided a conditional -* jump or a load/store address. So if we poison all of our inputs we -* can confirm that the operations in question are truly const time -* when compiled by whatever compiler is in use. -* -* Even better, the VALGRIND_MAKE_MEM_* macros work even when the -* program is not run under valgrind (though with a few cycles of -* overhead, which is unfortunate in final binaries as these -* annotations tend to be used in fairly important loops). -* -* This approach was first used in ctgrind (https://github.com/agl/ctgrind) -* but calling the valgrind mecheck API directly works just as well and -* doesn't require a custom patched valgrind. -*/ -template -inline void poison(const T* p, size_t n) - { + * Use valgrind to mark the contents of memory as being undefined. + * Valgrind will accept operations which manipulate undefined values, + * but will warn if an undefined value is used to decided a conditional + * jump or a load/store address. So if we poison all of our inputs we + * can confirm that the operations in question are truly const time + * when compiled by whatever compiler is in use. + * + * Even better, the VALGRIND_MAKE_MEM_* macros work even when the + * program is not run under valgrind (though with a few cycles of + * overhead, which is unfortunate in final binaries as these + * annotations tend to be used in fairly important loops). + * + * This approach was first used in ctgrind (https://github.com/agl/ctgrind) + * but calling the valgrind mecheck API directly works just as well and + * doesn't require a custom patched valgrind. + */ +template +inline void poison(const T* p, size_t n) { #if defined(BOTAN_HAS_VALGRIND) - VALGRIND_MAKE_MEM_UNDEFINED(p, n * sizeof(T)); + VALGRIND_MAKE_MEM_UNDEFINED(p, n * sizeof(T)); #else - BOTAN_UNUSED(p); - BOTAN_UNUSED(n); + BOTAN_UNUSED(p); + BOTAN_UNUSED(n); #endif - } +} -template -inline void unpoison(const T* p, size_t n) - { +template +inline void unpoison(const T* p, size_t n) { #if defined(BOTAN_HAS_VALGRIND) - VALGRIND_MAKE_MEM_DEFINED(p, n * sizeof(T)); + VALGRIND_MAKE_MEM_DEFINED(p, n * sizeof(T)); #else - BOTAN_UNUSED(p); - BOTAN_UNUSED(n); + BOTAN_UNUSED(p); + BOTAN_UNUSED(n); #endif - } +} -template -inline void unpoison(T& p) - { +template +inline void unpoison(T& p) { #if defined(BOTAN_HAS_VALGRIND) - VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(T)); + VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(T)); #else - BOTAN_UNUSED(p); + BOTAN_UNUSED(p); #endif - } +} /** -* A Mask type used for constant-time operations. A Mask always has value -* either 0 (all bits cleared) or ~0 (all bits set). All operations in a Mask -* are intended to compile to code which does not contain conditional jumps. -* This must be verified with tooling (eg binary disassembly or using valgrind) -* since you never know what a compiler might do. -*/ -template -class Mask - { + * A Mask type used for constant-time operations. A Mask always has value + * either 0 (all bits cleared) or ~0 (all bits set). All operations in a Mask + * are intended to compile to code which does not contain conditional jumps. + * This must be verified with tooling (eg binary disassembly or using valgrind) + * since you never know what a compiler might do. + */ +template +class Mask { public: - static_assert(std::is_unsigned::value, "CT::Mask only defined for unsigned integer types"); + static_assert(std::is_unsigned::value, "CT::Mask only defined for unsigned integer types"); - Mask(const Mask& other) = default; - Mask& operator=(const Mask& other) = default; + Mask(const Mask& other) = default; + Mask& operator=(const Mask& other) = default; - /** - * Derive a Mask from a Mask of a larger type - */ - template - Mask(Mask o) : m_mask(static_cast(o.value())) - { - static_assert(sizeof(U) > sizeof(T), "sizes ok"); - } + /** + * Derive a Mask from a Mask of a larger type + */ + template + Mask(Mask o) : m_mask(static_cast(o.value())) { + static_assert(sizeof(U) > sizeof(T), "sizes ok"); + } - /** - * Return a Mask with all bits set - */ - static Mask set() - { - return Mask(static_cast(~0)); - } + /** + * Return a Mask with all bits set + */ + static Mask set() { return Mask(static_cast(~0)); } - /** - * Return a Mask with all bits cleared - */ - static Mask cleared() - { - return Mask(0); - } + /** + * Return a Mask with all bits cleared + */ + static Mask cleared() { return Mask(0); } - /** - * Return a Mask which is set if v is != 0 - */ - static Mask expand(T v) - { - return ~Mask::is_zero(v); - } + /** + * Return a Mask which is set if v is != 0 + */ + static Mask expand(T v) { return ~Mask::is_zero(v); } - /** - * Return a Mask which is set if m is set - */ - template - static Mask expand(Mask m) - { - static_assert(sizeof(U) < sizeof(T), "sizes ok"); - return ~Mask::is_zero(m.value()); - } + /** + * Return a Mask which is set if m is set + */ + template + static Mask expand(Mask m) { + static_assert(sizeof(U) < sizeof(T), "sizes ok"); + return ~Mask::is_zero(m.value()); + } - /** - * Return a Mask which is set if v is == 0 or cleared otherwise - */ - static Mask is_zero(T x) - { - return Mask(ct_is_zero(x)); - } + /** + * Return a Mask which is set if v is == 0 or cleared otherwise + */ + static Mask is_zero(T x) { return Mask(ct_is_zero(x)); } - /** - * Return a Mask which is set if x == y - */ - static Mask is_equal(T x, T y) - { - return Mask::is_zero(static_cast(x ^ y)); - } + /** + * Return a Mask which is set if x == y + */ + static Mask is_equal(T x, T y) { return Mask::is_zero(static_cast(x ^ y)); } - /** - * Return a Mask which is set if x < y - */ - static Mask is_lt(T x, T y) - { - return Mask(expand_top_bit(x^((x^y) | ((x-y)^x)))); - } + /** + * Return a Mask which is set if x < y + */ + static Mask is_lt(T x, T y) { + return Mask(expand_top_bit(x ^ ((x ^ y) | ((x - y) ^ x)))); + } - /** - * Return a Mask which is set if x > y - */ - static Mask is_gt(T x, T y) - { - return Mask::is_lt(y, x); - } + /** + * Return a Mask which is set if x > y + */ + static Mask is_gt(T x, T y) { return Mask::is_lt(y, x); } - /** - * Return a Mask which is set if x <= y - */ - static Mask is_lte(T x, T y) - { - return ~Mask::is_gt(x, y); - } + /** + * Return a Mask which is set if x <= y + */ + static Mask is_lte(T x, T y) { return ~Mask::is_gt(x, y); } - /** - * Return a Mask which is set if x >= y - */ - static Mask is_gte(T x, T y) - { - return ~Mask::is_lt(x, y); - } + /** + * Return a Mask which is set if x >= y + */ + static Mask is_gte(T x, T y) { return ~Mask::is_lt(x, y); } - /** - * AND-combine two masks - */ - Mask& operator&=(Mask o) - { - m_mask &= o.value(); - return (*this); - } + /** + * AND-combine two masks + */ + Mask& operator&=(Mask o) { + m_mask &= o.value(); + return (*this); + } - /** - * XOR-combine two masks - */ - Mask& operator^=(Mask o) - { - m_mask ^= o.value(); - return (*this); - } + /** + * XOR-combine two masks + */ + Mask& operator^=(Mask o) { + m_mask ^= o.value(); + return (*this); + } - /** - * OR-combine two masks - */ - Mask& operator|=(Mask o) - { - m_mask |= o.value(); - return (*this); - } + /** + * OR-combine two masks + */ + Mask& operator|=(Mask o) { + m_mask |= o.value(); + return (*this); + } - /** - * AND-combine two masks - */ - friend Mask operator&(Mask x, Mask y) - { - return Mask(x.value() & y.value()); - } + /** + * AND-combine two masks + */ + friend Mask operator&(Mask x, Mask y) { return Mask(x.value() & y.value()); } - /** - * XOR-combine two masks - */ - friend Mask operator^(Mask x, Mask y) - { - return Mask(x.value() ^ y.value()); - } + /** + * XOR-combine two masks + */ + friend Mask operator^(Mask x, Mask y) { return Mask(x.value() ^ y.value()); } - /** - * OR-combine two masks - */ - friend Mask operator|(Mask x, Mask y) - { - return Mask(x.value() | y.value()); - } + /** + * OR-combine two masks + */ + friend Mask operator|(Mask x, Mask y) { return Mask(x.value() | y.value()); } - /** - * Negate this mask - */ - Mask operator~() const - { - return Mask(~value()); - } + /** + * Negate this mask + */ + Mask operator~() const { return Mask(~value()); } - /** - * Return x if the mask is set, or otherwise zero - */ - T if_set_return(T x) const - { - return m_mask & x; - } + /** + * Return x if the mask is set, or otherwise zero + */ + T if_set_return(T x) const { return m_mask & x; } - /** - * Return x if the mask is cleared, or otherwise zero - */ - T if_not_set_return(T x) const - { - return ~m_mask & x; - } + /** + * Return x if the mask is cleared, or otherwise zero + */ + T if_not_set_return(T x) const { return ~m_mask & x; } - /** - * If this mask is set, return x, otherwise return y - */ - T select(T x, T y) const - { - // (x & value()) | (y & ~value()) - return static_cast(y ^ (value() & (x ^ y))); - } + /** + * If this mask is set, return x, otherwise return y + */ + T select(T x, T y) const { + // (x & value()) | (y & ~value()) + return static_cast(y ^ (value() & (x ^ y))); + } - T select_and_unpoison(T x, T y) const - { - T r = this->select(x, y); - CT::unpoison(r); - return r; - } + T select_and_unpoison(T x, T y) const { + T r = this->select(x, y); + CT::unpoison(r); + return r; + } - /** - * If this mask is set, return x, otherwise return y - */ - Mask select_mask(Mask x, Mask y) const - { - return Mask(select(x.value(), y.value())); - } + /** + * If this mask is set, return x, otherwise return y + */ + Mask select_mask(Mask x, Mask y) const { + return Mask(select(x.value(), y.value())); + } - /** - * Conditionally set output to x or y, depending on if mask is set or - * cleared (resp) - */ - void select_n(T output[], const T x[], const T y[], size_t len) const - { - for(size_t i = 0; i != len; ++i) - output[i] = this->select(x[i], y[i]); - } + /** + * Conditionally set output to x or y, depending on if mask is set or + * cleared (resp) + */ + void select_n(T output[], const T x[], const T y[], size_t len) const { + for (size_t i = 0; i != len; ++i) output[i] = this->select(x[i], y[i]); + } - /** - * If this mask is set, zero out buf, otherwise do nothing - */ - void if_set_zero_out(T buf[], size_t elems) - { - for(size_t i = 0; i != elems; ++i) - { + /** + * If this mask is set, zero out buf, otherwise do nothing + */ + void if_set_zero_out(T buf[], size_t elems) { + for (size_t i = 0; i != elems; ++i) { buf[i] = this->if_not_set_return(buf[i]); - } - } + } + } - /** - * Return the value of the mask, unpoisoned - */ - T unpoisoned_value() const - { - T r = value(); - CT::unpoison(r); - return r; - } + /** + * Return the value of the mask, unpoisoned + */ + T unpoisoned_value() const { + T r = value(); + CT::unpoison(r); + return r; + } - /** - * Return true iff this mask is set - */ - bool is_set() const - { - return unpoisoned_value() != 0; - } + /** + * Return true iff this mask is set + */ + bool is_set() const { return unpoisoned_value() != 0; } - /** - * Return the underlying value of the mask - */ - T value() const - { - return m_mask; - } + /** + * Return the underlying value of the mask + */ + T value() const { return m_mask; } private: - Mask(T m) : m_mask(m) {} + Mask(T m) : m_mask(m) {} - T m_mask; - }; + T m_mask; +}; -template -inline Mask conditional_copy_mem(T cnd, - T* to, - const T* from0, - const T* from1, - size_t elems) - { - const auto mask = CT::Mask::expand(cnd); - mask.select_n(to, from0, from1, elems); - return mask; - } +template +inline Mask conditional_copy_mem(T cnd, T* to, const T* from0, const T* from1, size_t elems) { + const auto mask = CT::Mask::expand(cnd); + mask.select_n(to, from0, from1, elems); + return mask; +} -template -inline void conditional_swap(bool cnd, T& x, T& y) - { - const auto swap = CT::Mask::expand(cnd); +template +inline void conditional_swap(bool cnd, T& x, T& y) { + const auto swap = CT::Mask::expand(cnd); - T t0 = swap.select(y, x); - T t1 = swap.select(x, y); - x = t0; - y = t1; - } + T t0 = swap.select(y, x); + T t1 = swap.select(x, y); + x = t0; + y = t1; +} -template -inline void conditional_swap_ptr(bool cnd, T& x, T& y) - { - uintptr_t xp = reinterpret_cast(x); - uintptr_t yp = reinterpret_cast(y); +template +inline void conditional_swap_ptr(bool cnd, T& x, T& y) { + uintptr_t xp = reinterpret_cast(x); + uintptr_t yp = reinterpret_cast(y); - conditional_swap(cnd, xp, yp); + conditional_swap(cnd, xp, yp); - x = reinterpret_cast(xp); - y = reinterpret_cast(yp); - } + x = reinterpret_cast(xp); + y = reinterpret_cast(yp); +} /** -* If bad_mask is unset, return in[delim_idx:input_length] copied to -* new buffer. If bad_mask is set, return an all zero vector of -* unspecified length. -*/ -secure_vector copy_output(CT::Mask bad_input, - const uint8_t input[], - size_t input_length, - size_t delim_idx); + * If bad_mask is unset, return in[delim_idx:input_length] copied to + * new buffer. If bad_mask is set, return an all zero vector of + * unspecified length. + */ +secure_vector copy_output(CT::Mask bad_input, const uint8_t input[], + size_t input_length, size_t delim_idx); secure_vector strip_leading_zeros(const uint8_t in[], size_t length); -inline secure_vector strip_leading_zeros(const secure_vector& in) - { - return strip_leading_zeros(in.data(), in.size()); - } - +inline secure_vector strip_leading_zeros(const secure_vector& in) { + return strip_leading_zeros(in.data(), in.size()); } -} +} // namespace CT + +} // namespace Botan namespace Botan { -class donna128 final - { +class donna128 final { public: - donna128(uint64_t ll = 0, uint64_t hh = 0) { l = ll; h = hh; } + donna128(uint64_t ll = 0, uint64_t hh = 0) { + l = ll; + h = hh; + } - donna128(const donna128&) = default; - donna128& operator=(const donna128&) = default; + donna128(const donna128&) = default; + donna128& operator=(const donna128&) = default; - friend donna128 operator>>(const donna128& x, size_t shift) - { - donna128 z = x; - if(shift > 0) - { + friend donna128 operator>>(const donna128& x, size_t shift) { + donna128 z = x; + if (shift > 0) { const uint64_t carry = z.h << (64 - shift); z.h = (z.h >> shift); z.l = (z.l >> shift) | carry; - } - return z; - } + } + return z; + } - friend donna128 operator<<(const donna128& x, size_t shift) - { - donna128 z = x; - if(shift > 0) - { + friend donna128 operator<<(const donna128& x, size_t shift) { + donna128 z = x; + if (shift > 0) { const uint64_t carry = z.l >> (64 - shift); z.l = (z.l << shift); z.h = (z.h << shift) | carry; - } - return z; - } + } + return z; + } - friend uint64_t operator&(const donna128& x, uint64_t mask) - { - return x.l & mask; - } + friend uint64_t operator&(const donna128& x, uint64_t mask) { return x.l & mask; } - uint64_t operator&=(uint64_t mask) - { - h = 0; - l &= mask; - return l; - } + uint64_t operator&=(uint64_t mask) { + h = 0; + l &= mask; + return l; + } - donna128& operator+=(const donna128& x) - { - l += x.l; - h += x.h; + donna128& operator+=(const donna128& x) { + l += x.l; + h += x.h; - const uint64_t carry = (l < x.l); - h += carry; - return *this; - } + const uint64_t carry = (l < x.l); + h += carry; + return *this; + } - donna128& operator+=(uint64_t x) - { - l += x; - const uint64_t carry = (l < x); - h += carry; - return *this; - } + donna128& operator+=(uint64_t x) { + l += x; + const uint64_t carry = (l < x); + h += carry; + return *this; + } + + uint64_t lo() const { return l; } + uint64_t hi() const { return h; } - uint64_t lo() const { return l; } - uint64_t hi() const { return h; } private: - uint64_t h = 0, l = 0; - }; + uint64_t h = 0, l = 0; +}; -inline donna128 operator*(const donna128& x, uint64_t y) - { - BOTAN_ARG_CHECK(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply"); +inline donna128 operator*(const donna128& x, uint64_t y) { + BOTAN_ARG_CHECK(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply"); - uint64_t lo = 0, hi = 0; - mul64x64_128(x.lo(), y, &lo, &hi); - return donna128(lo, hi); - } + uint64_t lo = 0, hi = 0; + mul64x64_128(x.lo(), y, &lo, &hi); + return donna128(lo, hi); +} -inline donna128 operator*(uint64_t y, const donna128& x) - { - return x * y; - } +inline donna128 operator*(uint64_t y, const donna128& x) { return x * y; } -inline donna128 operator+(const donna128& x, const donna128& y) - { - donna128 z = x; - z += y; - return z; - } +inline donna128 operator+(const donna128& x, const donna128& y) { + donna128 z = x; + z += y; + return z; +} -inline donna128 operator+(const donna128& x, uint64_t y) - { - donna128 z = x; - z += y; - return z; - } +inline donna128 operator+(const donna128& x, uint64_t y) { + donna128 z = x; + z += y; + return z; +} -inline donna128 operator|(const donna128& x, const donna128& y) - { - return donna128(x.lo() | y.lo(), x.hi() | y.hi()); - } +inline donna128 operator|(const donna128& x, const donna128& y) { + return donna128(x.lo() | y.lo(), x.hi() | y.hi()); +} -inline uint64_t carry_shift(const donna128& a, size_t shift) - { - return (a >> shift).lo(); - } +inline uint64_t carry_shift(const donna128& a, size_t shift) { return (a >> shift).lo(); } -inline uint64_t combine_lower(const donna128& a, size_t s1, - const donna128& b, size_t s2) - { - donna128 z = (a >> s1) | (b << s2); - return z.lo(); - } +inline uint64_t combine_lower(const donna128& a, size_t s1, const donna128& b, size_t s2) { + donna128 z = (a >> s1) | (b << s2); + return z.lo(); +} #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128) -inline uint64_t carry_shift(const uint128_t a, size_t shift) - { - return static_cast(a >> shift); - } +inline uint64_t carry_shift(const uint128_t a, size_t shift) { + return static_cast(a >> shift); +} -inline uint64_t combine_lower(const uint128_t a, size_t s1, - const uint128_t b, size_t s2) - { - return static_cast((a >> s1) | (b << s2)); - } +inline uint64_t combine_lower(const uint128_t a, size_t s1, const uint128_t b, size_t s2) { + return static_cast((a >> s1) | (b << s2)); +} #endif -} +} // namespace Botan namespace Botan { /** -* No_Filesystem_Access Exception -*/ -class BOTAN_PUBLIC_API(2,0) No_Filesystem_Access final : public Exception - { + * No_Filesystem_Access Exception + */ +class BOTAN_PUBLIC_API(2, 0) No_Filesystem_Access final : public Exception { public: - No_Filesystem_Access() : Exception("No filesystem access enabled.") - {} - }; + No_Filesystem_Access() : Exception("No filesystem access enabled.") {} +}; BOTAN_TEST_API bool has_filesystem_impl(); BOTAN_TEST_API std::vector get_files_recursive(const std::string& dir); -} +} // namespace Botan namespace Botan { @@ -886,121 +744,117 @@ class Montgomery_Params; class Montgomery_Exponentation_State; /* -* Precompute for calculating values g^x mod p -*/ -std::shared_ptr -monty_precompute(std::shared_ptr params_p, - const BigInt& g, - size_t window_bits, - bool const_time = true); + * Precompute for calculating values g^x mod p + */ +std::shared_ptr monty_precompute( + std::shared_ptr params_p, const BigInt& g, size_t window_bits, + bool const_time = true); /* -* Return g^k mod p -*/ -BigInt monty_execute(const Montgomery_Exponentation_State& precomputed_state, - const BigInt& k, size_t max_k_bits); + * Return g^k mod p + */ +BigInt monty_execute(const Montgomery_Exponentation_State& precomputed_state, const BigInt& k, + size_t max_k_bits); /* -* Return g^k mod p taking variable time depending on k -* @warning only use this if k is public -*/ + * Return g^k mod p taking variable time depending on k + * @warning only use this if k is public + */ BigInt monty_execute_vartime(const Montgomery_Exponentation_State& precomputed_state, const BigInt& k); /** -* Return (x^z1 * y^z2) % p -*/ -BigInt monty_multi_exp(std::shared_ptr params_p, - const BigInt& x, - const BigInt& z1, - const BigInt& y, - const BigInt& z2); + * Return (x^z1 * y^z2) % p + */ +BigInt monty_multi_exp(std::shared_ptr params_p, const BigInt& x, + const BigInt& z1, const BigInt& y, const BigInt& z2); -} +} // namespace Botan namespace Botan { #if (BOTAN_MP_WORD_BITS == 32) - typedef uint64_t dword; - #define BOTAN_HAS_MP_DWORD +typedef uint64_t dword; +#define BOTAN_HAS_MP_DWORD #elif (BOTAN_MP_WORD_BITS == 64) - #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128) - typedef uint128_t dword; - #define BOTAN_HAS_MP_DWORD - #else - // No native 128 bit integer type; use mul64x64_128 instead - #endif +#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128) +typedef uint128_t dword; +#define BOTAN_HAS_MP_DWORD +#else +// No native 128 bit integer type; use mul64x64_128 instead +#endif #else - #error BOTAN_MP_WORD_BITS must be 32 or 64 +#error BOTAN_MP_WORD_BITS must be 32 or 64 #endif #if defined(BOTAN_TARGET_ARCH_IS_X86_32) && (BOTAN_MP_WORD_BITS == 32) - #if defined(BOTAN_USE_GCC_INLINE_ASM) - #define BOTAN_MP_USE_X86_32_ASM - #elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) - #define BOTAN_MP_USE_X86_32_MSVC_ASM - #endif +#if defined(BOTAN_USE_GCC_INLINE_ASM) +#define BOTAN_MP_USE_X86_32_ASM +#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) +#define BOTAN_MP_USE_X86_32_MSVC_ASM +#endif -#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && (BOTAN_MP_WORD_BITS == 64) && defined(BOTAN_USE_GCC_INLINE_ASM) - #define BOTAN_MP_USE_X86_64_ASM +#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && (BOTAN_MP_WORD_BITS == 64) && \ + defined(BOTAN_USE_GCC_INLINE_ASM) +#define BOTAN_MP_USE_X86_64_ASM #endif /* -* Word Multiply/Add -*/ -inline word word_madd2(word a, word b, word* c) - { + * Word Multiply/Add + */ +inline word word_madd2(word a, word b, word* c) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm(R"( + asm(R"( mull %[b] addl %[c],%[a] adcl $0,%[carry] )" - : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*c) - : "0"(a), "1"(b), [c]"g"(*c) : "cc"); + : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*c) + : "0"(a), "1"(b), [c] "g"(*c) + : "cc"); - return a; + return a; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm(R"( + asm(R"( mulq %[b] addq %[c],%[a] adcq $0,%[carry] )" - : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*c) - : "0"(a), "1"(b), [c]"g"(*c) : "cc"); + : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*c) + : "0"(a), "1"(b), [c] "g"(*c) + : "cc"); - return a; + return a; #elif defined(BOTAN_HAS_MP_DWORD) - const dword s = static_cast(a) * b + *c; - *c = static_cast(s >> BOTAN_MP_WORD_BITS); - return static_cast(s); + const dword s = static_cast(a) * b + *c; + *c = static_cast(s >> BOTAN_MP_WORD_BITS); + return static_cast(s); #else - static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size"); + static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size"); - word hi = 0, lo = 0; + word hi = 0, lo = 0; - mul64x64_128(a, b, &lo, &hi); + mul64x64_128(a, b, &lo, &hi); - lo += *c; - hi += (lo < *c); // carry? + lo += *c; + hi += (lo < *c); // carry? - *c = hi; - return lo; + *c = hi; + return lo; #endif - } +} /* -* Word Multiply/Add -*/ -inline word word_madd3(word a, word b, word c, word* d) - { + * Word Multiply/Add + */ +inline word word_madd3(word a, word b, word c, word* d) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm(R"( + asm(R"( mull %[b] addl %[c],%[a] @@ -1009,119 +863,121 @@ inline word word_madd3(word a, word b, word c, word* d) addl %[d],%[a] adcl $0,%[carry] )" - : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*d) - : "0"(a), "1"(b), [c]"g"(c), [d]"g"(*d) : "cc"); + : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*d) + : "0"(a), "1"(b), [c] "g"(c), [d] "g"(*d) + : "cc"); - return a; + return a; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm(R"( + asm(R"( mulq %[b] addq %[c],%[a] adcq $0,%[carry] addq %[d],%[a] adcq $0,%[carry] )" - : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*d) - : "0"(a), "1"(b), [c]"g"(c), [d]"g"(*d) : "cc"); + : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*d) + : "0"(a), "1"(b), [c] "g"(c), [d] "g"(*d) + : "cc"); - return a; + return a; #elif defined(BOTAN_HAS_MP_DWORD) - const dword s = static_cast(a) * b + c + *d; - *d = static_cast(s >> BOTAN_MP_WORD_BITS); - return static_cast(s); + const dword s = static_cast(a) * b + c + *d; + *d = static_cast(s >> BOTAN_MP_WORD_BITS); + return static_cast(s); #else - static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size"); + static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size"); - word hi = 0, lo = 0; + word hi = 0, lo = 0; - mul64x64_128(a, b, &lo, &hi); + mul64x64_128(a, b, &lo, &hi); - lo += c; - hi += (lo < c); // carry? + lo += c; + hi += (lo < c); // carry? - lo += *d; - hi += (lo < *d); // carry? + lo += *d; + hi += (lo < *d); // carry? - *d = hi; - return lo; + *d = hi; + return lo; #endif - } - } +} // namespace Botan + namespace Botan { #if defined(BOTAN_MP_USE_X86_32_ASM) -#define ADDSUB2_OP(OPERATION, INDEX) \ - ASM("movl 4*" #INDEX "(%[y]), %[carry]") \ - ASM(OPERATION " %[carry], 4*" #INDEX "(%[x])") \ +#define ADDSUB2_OP(OPERATION, INDEX) \ + ASM("movl 4*" #INDEX "(%[y]), %[carry]") \ + ASM(OPERATION " %[carry], 4*" #INDEX "(%[x])") -#define ADDSUB3_OP(OPERATION, INDEX) \ - ASM("movl 4*" #INDEX "(%[x]), %[carry]") \ - ASM(OPERATION " 4*" #INDEX "(%[y]), %[carry]") \ - ASM("movl %[carry], 4*" #INDEX "(%[z])") \ +#define ADDSUB3_OP(OPERATION, INDEX) \ + ASM("movl 4*" #INDEX "(%[x]), %[carry]") \ + ASM(OPERATION " 4*" #INDEX "(%[y]), %[carry]") \ + ASM("movl %[carry], 4*" #INDEX "(%[z])") -#define LINMUL_OP(WRITE_TO, INDEX) \ - ASM("movl 4*" #INDEX "(%[x]),%%eax") \ - ASM("mull %[y]") \ - ASM("addl %[carry],%%eax") \ - ASM("adcl $0,%%edx") \ - ASM("movl %%edx,%[carry]") \ - ASM("movl %%eax, 4*" #INDEX "(%[" WRITE_TO "])") +#define LINMUL_OP(WRITE_TO, INDEX) \ + ASM("movl 4*" #INDEX "(%[x]),%%eax") \ + ASM("mull %[y]") \ + ASM("addl %[carry],%%eax") \ + ASM("adcl $0,%%edx") \ + ASM("movl %%edx,%[carry]") \ + ASM("movl %%eax, 4*" #INDEX "(%[" WRITE_TO "])") -#define MULADD_OP(IGNORED, INDEX) \ - ASM("movl 4*" #INDEX "(%[x]),%%eax") \ - ASM("mull %[y]") \ - ASM("addl %[carry],%%eax") \ - ASM("adcl $0,%%edx") \ - ASM("addl 4*" #INDEX "(%[z]),%%eax") \ - ASM("adcl $0,%%edx") \ - ASM("movl %%edx,%[carry]") \ - ASM("movl %%eax, 4*" #INDEX " (%[z])") +#define MULADD_OP(IGNORED, INDEX) \ + ASM("movl 4*" #INDEX "(%[x]),%%eax") \ + ASM("mull %[y]") \ + ASM("addl %[carry],%%eax") \ + ASM("adcl $0,%%edx") \ + ASM("addl 4*" #INDEX "(%[z]),%%eax") \ + ASM("adcl $0,%%edx") \ + ASM("movl %%edx,%[carry]") \ + ASM("movl %%eax, 4*" #INDEX " (%[z])") -#define ADD_OR_SUBTRACT(CORE_CODE) \ - ASM("rorl %[carry]") \ - CORE_CODE \ - ASM("sbbl %[carry],%[carry]") \ - ASM("negl %[carry]") +#define ADD_OR_SUBTRACT(CORE_CODE) \ + ASM("rorl %[carry]") \ + CORE_CODE \ + ASM("sbbl %[carry],%[carry]") \ + ASM("negl %[carry]") #elif defined(BOTAN_MP_USE_X86_64_ASM) -#define ADDSUB2_OP(OPERATION, INDEX) \ - ASM("movq 8*" #INDEX "(%[y]), %[carry]") \ - ASM(OPERATION " %[carry], 8*" #INDEX "(%[x])") \ +#define ADDSUB2_OP(OPERATION, INDEX) \ + ASM("movq 8*" #INDEX "(%[y]), %[carry]") \ + ASM(OPERATION " %[carry], 8*" #INDEX "(%[x])") -#define ADDSUB3_OP(OPERATION, INDEX) \ - ASM("movq 8*" #INDEX "(%[x]), %[carry]") \ - ASM(OPERATION " 8*" #INDEX "(%[y]), %[carry]") \ - ASM("movq %[carry], 8*" #INDEX "(%[z])") \ +#define ADDSUB3_OP(OPERATION, INDEX) \ + ASM("movq 8*" #INDEX "(%[x]), %[carry]") \ + ASM(OPERATION " 8*" #INDEX "(%[y]), %[carry]") \ + ASM("movq %[carry], 8*" #INDEX "(%[z])") -#define LINMUL_OP(WRITE_TO, INDEX) \ - ASM("movq 8*" #INDEX "(%[x]),%%rax") \ - ASM("mulq %[y]") \ - ASM("addq %[carry],%%rax") \ - ASM("adcq $0,%%rdx") \ - ASM("movq %%rdx,%[carry]") \ - ASM("movq %%rax, 8*" #INDEX "(%[" WRITE_TO "])") +#define LINMUL_OP(WRITE_TO, INDEX) \ + ASM("movq 8*" #INDEX "(%[x]),%%rax") \ + ASM("mulq %[y]") \ + ASM("addq %[carry],%%rax") \ + ASM("adcq $0,%%rdx") \ + ASM("movq %%rdx,%[carry]") \ + ASM("movq %%rax, 8*" #INDEX "(%[" WRITE_TO "])") -#define MULADD_OP(IGNORED, INDEX) \ - ASM("movq 8*" #INDEX "(%[x]),%%rax") \ - ASM("mulq %[y]") \ - ASM("addq %[carry],%%rax") \ - ASM("adcq $0,%%rdx") \ - ASM("addq 8*" #INDEX "(%[z]),%%rax") \ - ASM("adcq $0,%%rdx") \ - ASM("movq %%rdx,%[carry]") \ - ASM("movq %%rax, 8*" #INDEX " (%[z])") +#define MULADD_OP(IGNORED, INDEX) \ + ASM("movq 8*" #INDEX "(%[x]),%%rax") \ + ASM("mulq %[y]") \ + ASM("addq %[carry],%%rax") \ + ASM("adcq $0,%%rdx") \ + ASM("addq 8*" #INDEX "(%[z]),%%rax") \ + ASM("adcq $0,%%rdx") \ + ASM("movq %%rdx,%[carry]") \ + ASM("movq %%rax, 8*" #INDEX " (%[z])") -#define ADD_OR_SUBTRACT(CORE_CODE) \ - ASM("rorq %[carry]") \ - CORE_CODE \ - ASM("sbbq %[carry],%[carry]") \ - ASM("negq %[carry]") +#define ADD_OR_SUBTRACT(CORE_CODE) \ + ASM("rorq %[carry]") \ + CORE_CODE \ + ASM("sbbq %[carry],%[carry]") \ + ASM("negq %[carry]") #endif @@ -1130,77 +986,71 @@ namespace Botan { #define ASM(x) x "\n\t" #define DO_8_TIMES(MACRO, ARG) \ - MACRO(ARG, 0) \ - MACRO(ARG, 1) \ - MACRO(ARG, 2) \ - MACRO(ARG, 3) \ - MACRO(ARG, 4) \ - MACRO(ARG, 5) \ - MACRO(ARG, 6) \ - MACRO(ARG, 7) + MACRO(ARG, 0) \ + MACRO(ARG, 1) \ + MACRO(ARG, 2) \ + MACRO(ARG, 3) \ + MACRO(ARG, 4) \ + MACRO(ARG, 5) \ + MACRO(ARG, 6) \ + MACRO(ARG, 7) #endif /* -* Word Addition -*/ -inline word word_add(word x, word y, word* carry) - { + * Word Addition + */ +inline word word_add(word x, word y, word* carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - ADD_OR_SUBTRACT(ASM("adcl %[y],%[x]")) - : [x]"=r"(x), [carry]"=r"(*carry) - : "0"(x), [y]"rm"(y), "1"(*carry) - : "cc"); - return x; + asm(ADD_OR_SUBTRACT(ASM("adcl %[y],%[x]")) + : [x] "=r"(x), [carry] "=r"(*carry) + : "0"(x), [y] "rm"(y), "1"(*carry) + : "cc"); + return x; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - ADD_OR_SUBTRACT(ASM("adcq %[y],%[x]")) - : [x]"=r"(x), [carry]"=r"(*carry) - : "0"(x), [y]"rm"(y), "1"(*carry) - : "cc"); - return x; + asm(ADD_OR_SUBTRACT(ASM("adcq %[y],%[x]")) + : [x] "=r"(x), [carry] "=r"(*carry) + : "0"(x), [y] "rm"(y), "1"(*carry) + : "cc"); + return x; #else - word z = x + y; - word c1 = (z < x); - z += *carry; - *carry = c1 | (z < *carry); - return z; + word z = x + y; + word c1 = (z < x); + z += *carry; + *carry = c1 | (z < *carry); + return z; #endif - } +} /* -* Eight Word Block Addition, Two Argument -*/ -inline word word8_add2(word x[8], const word y[8], word carry) - { + * Eight Word Block Addition, Two Argument + */ +inline word word8_add2(word x[8], const word y[8], word carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcl")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcl")) + : [carry] "=r"(carry) + : [x] "r"(x), [y] "r"(y), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcq")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcq")) + : [carry] "=r"(carry) + : [x] "r"(x), [y] "r"(y), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) - __asm { + __asm { mov edx,[x] mov esi,[y] xor eax,eax - sub eax,[carry] //force CF=1 iff *carry==1 + sub eax,[carry] // force CF=1 iff *carry==1 mov eax,[esi] adc [edx],eax mov eax,[esi+4] @@ -1219,43 +1069,39 @@ inline word word8_add2(word x[8], const word y[8], word carry) adc [edx+28],eax sbb eax,eax neg eax - } + } #else - x[0] = word_add(x[0], y[0], &carry); - x[1] = word_add(x[1], y[1], &carry); - x[2] = word_add(x[2], y[2], &carry); - x[3] = word_add(x[3], y[3], &carry); - x[4] = word_add(x[4], y[4], &carry); - x[5] = word_add(x[5], y[5], &carry); - x[6] = word_add(x[6], y[6], &carry); - x[7] = word_add(x[7], y[7], &carry); - return carry; + x[0] = word_add(x[0], y[0], &carry); + x[1] = word_add(x[1], y[1], &carry); + x[2] = word_add(x[2], y[2], &carry); + x[3] = word_add(x[3], y[3], &carry); + x[4] = word_add(x[4], y[4], &carry); + x[5] = word_add(x[5], y[5], &carry); + x[6] = word_add(x[6], y[6], &carry); + x[7] = word_add(x[7], y[7], &carry); + return carry; #endif - } +} /* -* Eight Word Block Addition, Three Argument -*/ -inline word word8_add3(word z[8], const word x[8], - const word y[8], word carry) - { + * Eight Word Block Addition, Three Argument + */ +inline word word8_add3(word z[8], const word x[8], const word y[8], word carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcl")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcl")) + : [carry] "=r"(carry) + : [x] "r"(x), [y] "r"(y), [z] "r"(z), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcq")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcq")) + : [carry] "=r"(carry) + : [x] "r"(x), [y] "r"(y), [z] "r"(z), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) @@ -1264,7 +1110,7 @@ inline word word8_add3(word z[8], const word x[8], mov esi,[y] mov ebx,[z] xor eax,eax - sub eax,[carry] //force CF=1 iff *carry==1 + sub eax,[carry] // force CF=1 iff *carry==1 mov eax,[edi] adc eax,[esi] mov [ebx],eax @@ -1299,73 +1145,67 @@ inline word word8_add3(word z[8], const word x[8], sbb eax,eax neg eax - } + } #else - z[0] = word_add(x[0], y[0], &carry); - z[1] = word_add(x[1], y[1], &carry); - z[2] = word_add(x[2], y[2], &carry); - z[3] = word_add(x[3], y[3], &carry); - z[4] = word_add(x[4], y[4], &carry); - z[5] = word_add(x[5], y[5], &carry); - z[6] = word_add(x[6], y[6], &carry); - z[7] = word_add(x[7], y[7], &carry); - return carry; + z[0] = word_add(x[0], y[0], &carry); + z[1] = word_add(x[1], y[1], &carry); + z[2] = word_add(x[2], y[2], &carry); + z[3] = word_add(x[3], y[3], &carry); + z[4] = word_add(x[4], y[4], &carry); + z[5] = word_add(x[5], y[5], &carry); + z[6] = word_add(x[6], y[6], &carry); + z[7] = word_add(x[7], y[7], &carry); + return carry; #endif - } +} /* -* Word Subtraction -*/ -inline word word_sub(word x, word y, word* carry) - { + * Word Subtraction + */ +inline word word_sub(word x, word y, word* carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - ADD_OR_SUBTRACT(ASM("sbbl %[y],%[x]")) - : [x]"=r"(x), [carry]"=r"(*carry) - : "0"(x), [y]"rm"(y), "1"(*carry) - : "cc"); - return x; + asm(ADD_OR_SUBTRACT(ASM("sbbl %[y],%[x]")) + : [x] "=r"(x), [carry] "=r"(*carry) + : "0"(x), [y] "rm"(y), "1"(*carry) + : "cc"); + return x; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - ADD_OR_SUBTRACT(ASM("sbbq %[y],%[x]")) - : [x]"=r"(x), [carry]"=r"(*carry) - : "0"(x), [y]"rm"(y), "1"(*carry) - : "cc"); - return x; + asm(ADD_OR_SUBTRACT(ASM("sbbq %[y],%[x]")) + : [x] "=r"(x), [carry] "=r"(*carry) + : "0"(x), [y] "rm"(y), "1"(*carry) + : "cc"); + return x; #else - word t0 = x - y; - word c1 = (t0 > x); - word z = t0 - *carry; - *carry = c1 | (z > t0); - return z; + word t0 = x - y; + word c1 = (t0 > x); + word z = t0 - *carry; + *carry = c1 | (z > t0); + return z; #endif - } +} /* -* Eight Word Block Subtraction, Two Argument -*/ -inline word word8_sub2(word x[8], const word y[8], word carry) - { + * Eight Word Block Subtraction, Two Argument + */ +inline word word8_sub2(word x[8], const word y[8], word carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbl")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbl")) + : [carry] "=r"(carry) + : [x] "r"(x), [y] "r"(y), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbq")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbq")) + : [carry] "=r"(carry) + : [x] "r"(x), [y] "r"(y), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) @@ -1373,7 +1213,7 @@ inline word word8_sub2(word x[8], const word y[8], word carry) mov edi,[x] mov esi,[y] xor eax,eax - sub eax,[carry] //force CF=1 iff *carry==1 + sub eax,[carry] // force CF=1 iff *carry==1 mov eax,[edi] sbb eax,[esi] mov [edi],eax @@ -1400,86 +1240,79 @@ inline word word8_sub2(word x[8], const word y[8], word carry) mov [edi+28],eax sbb eax,eax neg eax - } + } #else - x[0] = word_sub(x[0], y[0], &carry); - x[1] = word_sub(x[1], y[1], &carry); - x[2] = word_sub(x[2], y[2], &carry); - x[3] = word_sub(x[3], y[3], &carry); - x[4] = word_sub(x[4], y[4], &carry); - x[5] = word_sub(x[5], y[5], &carry); - x[6] = word_sub(x[6], y[6], &carry); - x[7] = word_sub(x[7], y[7], &carry); - return carry; + x[0] = word_sub(x[0], y[0], &carry); + x[1] = word_sub(x[1], y[1], &carry); + x[2] = word_sub(x[2], y[2], &carry); + x[3] = word_sub(x[3], y[3], &carry); + x[4] = word_sub(x[4], y[4], &carry); + x[5] = word_sub(x[5], y[5], &carry); + x[6] = word_sub(x[6], y[6], &carry); + x[7] = word_sub(x[7], y[7], &carry); + return carry; #endif - } +} /* -* Eight Word Block Subtraction, Two Argument -*/ -inline word word8_sub2_rev(word x[8], const word y[8], word carry) - { + * Eight Word Block Subtraction, Two Argument + */ +inline word word8_sub2_rev(word x[8], const word y[8], word carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbl")) - : [carry]"=r"(carry) - : [x]"r"(y), [y]"r"(x), [z]"r"(x), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbl")) + : [carry] "=r"(carry) + : [x] "r"(y), [y] "r"(x), [z] "r"(x), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbq")) - : [carry]"=r"(carry) - : [x]"r"(y), [y]"r"(x), [z]"r"(x), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbq")) + : [carry] "=r"(carry) + : [x] "r"(y), [y] "r"(x), [z] "r"(x), "0"(carry) + : "cc", "memory"); + return carry; #else - x[0] = word_sub(y[0], x[0], &carry); - x[1] = word_sub(y[1], x[1], &carry); - x[2] = word_sub(y[2], x[2], &carry); - x[3] = word_sub(y[3], x[3], &carry); - x[4] = word_sub(y[4], x[4], &carry); - x[5] = word_sub(y[5], x[5], &carry); - x[6] = word_sub(y[6], x[6], &carry); - x[7] = word_sub(y[7], x[7], &carry); - return carry; + x[0] = word_sub(y[0], x[0], &carry); + x[1] = word_sub(y[1], x[1], &carry); + x[2] = word_sub(y[2], x[2], &carry); + x[3] = word_sub(y[3], x[3], &carry); + x[4] = word_sub(y[4], x[4], &carry); + x[5] = word_sub(y[5], x[5], &carry); + x[6] = word_sub(y[6], x[6], &carry); + x[7] = word_sub(y[7], x[7], &carry); + return carry; #endif - } +} /* -* Eight Word Block Subtraction, Three Argument -*/ -inline word word8_sub3(word z[8], const word x[8], - const word y[8], word carry) - { + * Eight Word Block Subtraction, Three Argument + */ +inline word word8_sub3(word z[8], const word x[8], const word y[8], word carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbl")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbl")) + : [carry] "=r"(carry) + : [x] "r"(x), [y] "r"(y), [z] "r"(z), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbq")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) - : "cc", "memory"); - return carry; + asm(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbq")) + : [carry] "=r"(carry) + : [x] "r"(x), [y] "r"(y), [z] "r"(z), "0"(carry) + : "cc", "memory"); + return carry; #elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) - __asm { + __asm { mov edi,[x] mov esi,[y] xor eax,eax - sub eax,[carry] //force CF=1 iff *carry==1 + sub eax,[carry] // force CF=1 iff *carry==1 mov ebx,[z] mov eax,[edi] sbb eax,[esi] @@ -1507,350 +1340,329 @@ inline word word8_sub3(word z[8], const word x[8], mov [ebx+28],eax sbb eax,eax neg eax - } + } #else - z[0] = word_sub(x[0], y[0], &carry); - z[1] = word_sub(x[1], y[1], &carry); - z[2] = word_sub(x[2], y[2], &carry); - z[3] = word_sub(x[3], y[3], &carry); - z[4] = word_sub(x[4], y[4], &carry); - z[5] = word_sub(x[5], y[5], &carry); - z[6] = word_sub(x[6], y[6], &carry); - z[7] = word_sub(x[7], y[7], &carry); - return carry; + z[0] = word_sub(x[0], y[0], &carry); + z[1] = word_sub(x[1], y[1], &carry); + z[2] = word_sub(x[2], y[2], &carry); + z[3] = word_sub(x[3], y[3], &carry); + z[4] = word_sub(x[4], y[4], &carry); + z[5] = word_sub(x[5], y[5], &carry); + z[6] = word_sub(x[6], y[6], &carry); + z[7] = word_sub(x[7], y[7], &carry); + return carry; #endif - } +} /* -* Eight Word Block Linear Multiplication -*/ -inline word word8_linmul2(word x[8], word y, word carry) - { + * Eight Word Block Linear Multiplication + */ +inline word word8_linmul2(word x[8], word y, word carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - DO_8_TIMES(LINMUL_OP, "x") - : [carry]"=r"(carry) - : [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%eax", "%edx"); - return carry; + asm(DO_8_TIMES(LINMUL_OP, "x") + : [carry] "=r"(carry) + : [x] "r"(x), [y] "rm"(y), "0"(carry) + : "cc", "%eax", "%edx"); + return carry; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - DO_8_TIMES(LINMUL_OP, "x") - : [carry]"=r"(carry) - : [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%rax", "%rdx"); - return carry; + asm(DO_8_TIMES(LINMUL_OP, "x") + : [carry] "=r"(carry) + : [x] "r"(x), [y] "rm"(y), "0"(carry) + : "cc", "%rax", "%rdx"); + return carry; #elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) - __asm { + __asm { mov esi,[x] - mov eax,[esi] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,[carry] //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [esi],eax //load a + mov eax,[esi] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,[carry] // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [esi],eax // load a - mov eax,[esi+4] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [esi+4],eax //load a + mov eax,[esi+4] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [esi+4],eax // load a - mov eax,[esi+8] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [esi+8],eax //load a + mov eax,[esi+8] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [esi+8],eax // load a - mov eax,[esi+12] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [esi+12],eax //load a + mov eax,[esi+12] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [esi+12],eax // load a - mov eax,[esi+16] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [esi+16],eax //load a + mov eax,[esi+16] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [esi+16],eax // load a - mov eax,[esi+20] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [esi+20],eax //load a + mov eax,[esi+20] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [esi+20],eax // load a - mov eax,[esi+24] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [esi+24],eax //load a + mov eax,[esi+24] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [esi+24],eax // load a - mov eax,[esi+28] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov [esi+28],eax //load a + mov eax,[esi+28] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov [esi+28],eax // load a - mov eax,edx //store carry - } + mov eax,edx // store carry + } #else - x[0] = word_madd2(x[0], y, &carry); - x[1] = word_madd2(x[1], y, &carry); - x[2] = word_madd2(x[2], y, &carry); - x[3] = word_madd2(x[3], y, &carry); - x[4] = word_madd2(x[4], y, &carry); - x[5] = word_madd2(x[5], y, &carry); - x[6] = word_madd2(x[6], y, &carry); - x[7] = word_madd2(x[7], y, &carry); - return carry; + x[0] = word_madd2(x[0], y, &carry); + x[1] = word_madd2(x[1], y, &carry); + x[2] = word_madd2(x[2], y, &carry); + x[3] = word_madd2(x[3], y, &carry); + x[4] = word_madd2(x[4], y, &carry); + x[5] = word_madd2(x[5], y, &carry); + x[6] = word_madd2(x[6], y, &carry); + x[7] = word_madd2(x[7], y, &carry); + return carry; #endif - } +} /* -* Eight Word Block Linear Multiplication -*/ -inline word word8_linmul3(word z[8], const word x[8], word y, word carry) - { + * Eight Word Block Linear Multiplication + */ +inline word word8_linmul3(word z[8], const word x[8], word y, word carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - DO_8_TIMES(LINMUL_OP, "z") - : [carry]"=r"(carry) - : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%eax", "%edx"); - return carry; + asm(DO_8_TIMES(LINMUL_OP, "z") + : [carry] "=r"(carry) + : [z] "r"(z), [x] "r"(x), [y] "rm"(y), "0"(carry) + : "cc", "%eax", "%edx"); + return carry; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - DO_8_TIMES(LINMUL_OP, "z") - : [carry]"=r"(carry) - : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%rax", "%rdx"); - return carry; + asm(DO_8_TIMES(LINMUL_OP, "z") + : [carry] "=r"(carry) + : [z] "r"(z), [x] "r"(x), [y] "rm"(y), "0"(carry) + : "cc", "%rax", "%rdx"); + return carry; #elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) - __asm { + __asm { mov edi,[z] mov esi,[x] - mov eax,[esi] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,[carry] //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [edi],eax //load a + mov eax,[esi] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,[carry] // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [edi],eax // load a - mov eax,[esi+4] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [edi+4],eax //load a + mov eax,[esi+4] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [edi+4],eax // load a - mov eax,[esi+8] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [edi+8],eax //load a + mov eax,[esi+8] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [edi+8],eax // load a - mov eax,[esi+12] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [edi+12],eax //load a + mov eax,[esi+12] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [edi+12],eax // load a - mov eax,[esi+16] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [edi+16],eax //load a + mov eax,[esi+16] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [edi+16],eax // load a - mov eax,[esi+20] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [edi+20],eax //load a + mov eax,[esi+20] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [edi+20],eax // load a - mov eax,[esi+24] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov ecx,edx //store carry - mov [edi+24],eax //load a + mov eax,[esi+24] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov ecx,edx // store carry + mov [edi+24],eax // load a - mov eax,[esi+28] //load a - mul [y] //edx(hi):eax(lo)=a*b - add eax,ecx //sum lo carry - adc edx,0 //sum hi carry - mov [edi+28],eax //load a - mov eax,edx //store carry - } + mov eax,[esi+28] // load a + mul [y] // edx(hi):eax(lo)=a*b + add eax,ecx // sum lo carry + adc edx,0 // sum hi carry + mov [edi+28],eax // load a + mov eax,edx // store carry + } #else - z[0] = word_madd2(x[0], y, &carry); - z[1] = word_madd2(x[1], y, &carry); - z[2] = word_madd2(x[2], y, &carry); - z[3] = word_madd2(x[3], y, &carry); - z[4] = word_madd2(x[4], y, &carry); - z[5] = word_madd2(x[5], y, &carry); - z[6] = word_madd2(x[6], y, &carry); - z[7] = word_madd2(x[7], y, &carry); - return carry; + z[0] = word_madd2(x[0], y, &carry); + z[1] = word_madd2(x[1], y, &carry); + z[2] = word_madd2(x[2], y, &carry); + z[3] = word_madd2(x[3], y, &carry); + z[4] = word_madd2(x[4], y, &carry); + z[5] = word_madd2(x[5], y, &carry); + z[6] = word_madd2(x[6], y, &carry); + z[7] = word_madd2(x[7], y, &carry); + return carry; #endif - } +} /* -* Eight Word Block Multiply/Add -*/ -inline word word8_madd3(word z[8], const word x[8], word y, word carry) - { + * Eight Word Block Multiply/Add + */ +inline word word8_madd3(word z[8], const word x[8], word y, word carry) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm( - DO_8_TIMES(MULADD_OP, "") - : [carry]"=r"(carry) - : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%eax", "%edx"); - return carry; + asm(DO_8_TIMES(MULADD_OP, "") + : [carry] "=r"(carry) + : [z] "r"(z), [x] "r"(x), [y] "rm"(y), "0"(carry) + : "cc", "%eax", "%edx"); + return carry; #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm( - DO_8_TIMES(MULADD_OP, "") - : [carry]"=r"(carry) - : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%rax", "%rdx"); - return carry; + asm(DO_8_TIMES(MULADD_OP, "") + : [carry] "=r"(carry) + : [z] "r"(z), [x] "r"(x), [y] "rm"(y), "0"(carry) + : "cc", "%rax", "%rdx"); + return carry; #else - z[0] = word_madd3(x[0], y, z[0], &carry); - z[1] = word_madd3(x[1], y, z[1], &carry); - z[2] = word_madd3(x[2], y, z[2], &carry); - z[3] = word_madd3(x[3], y, z[3], &carry); - z[4] = word_madd3(x[4], y, z[4], &carry); - z[5] = word_madd3(x[5], y, z[5], &carry); - z[6] = word_madd3(x[6], y, z[6], &carry); - z[7] = word_madd3(x[7], y, z[7], &carry); - return carry; + z[0] = word_madd3(x[0], y, z[0], &carry); + z[1] = word_madd3(x[1], y, z[1], &carry); + z[2] = word_madd3(x[2], y, z[2], &carry); + z[3] = word_madd3(x[3], y, z[3], &carry); + z[4] = word_madd3(x[4], y, z[4], &carry); + z[5] = word_madd3(x[5], y, z[5], &carry); + z[6] = word_madd3(x[6], y, z[6], &carry); + z[7] = word_madd3(x[7], y, z[7], &carry); + return carry; #endif - } +} /* -* Multiply-Add Accumulator -* (w2,w1,w0) += x * y -*/ -inline void word3_muladd(word* w2, word* w1, word* w0, word x, word y) - { + * Multiply-Add Accumulator + * (w2,w1,w0) += x * y + */ +inline void word3_muladd(word* w2, word* w1, word* w0, word x, word y) { #if defined(BOTAN_MP_USE_X86_32_ASM) - word z0 = 0, z1 = 0; + word z0 = 0, z1 = 0; - asm("mull %[y]" - : "=a"(z0),"=d"(z1) - : "a"(x), [y]"rm"(y) - : "cc"); + asm("mull %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc"); - asm(R"( + asm(R"( addl %[z0],%[w0] adcl %[z1],%[w1] adcl $0,%[w2] )" - : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) - : [z0]"r"(z0), [z1]"r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) - : "cc"); + : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2) + : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); #elif defined(BOTAN_MP_USE_X86_64_ASM) - word z0 = 0, z1 = 0; + word z0 = 0, z1 = 0; - asm("mulq %[y]" - : "=a"(z0),"=d"(z1) - : "a"(x), [y]"rm"(y) - : "cc"); + asm("mulq %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc"); - asm(R"( + asm(R"( addq %[z0],%[w0] adcq %[z1],%[w1] adcq $0,%[w2] )" - : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) - : [z0]"r"(z0), [z1]"r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) - : "cc"); + : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2) + : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); #else - word carry = *w0; - *w0 = word_madd2(x, y, &carry); - *w1 += carry; - *w2 += (*w1 < carry); + word carry = *w0; + *w0 = word_madd2(x, y, &carry); + *w1 += carry; + *w2 += (*w1 < carry); #endif - } +} /* -* 3-word addition -* (w2,w1,w0) += x -*/ -inline void word3_add(word* w2, word* w1, word* w0, word x) - { + * 3-word addition + * (w2,w1,w0) += x + */ +inline void word3_add(word* w2, word* w1, word* w0, word x) { #if defined(BOTAN_MP_USE_X86_32_ASM) - asm(R"( + asm(R"( addl %[x],%[w0] adcl $0,%[w1] adcl $0,%[w2] )" - : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) - : [x]"r"(x), "0"(*w0), "1"(*w1), "2"(*w2) - : "cc"); + : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2) + : [x] "r"(x), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); #elif defined(BOTAN_MP_USE_X86_64_ASM) - asm(R"( + asm(R"( addq %[x],%[w0] adcq $0,%[w1] adcq $0,%[w2] )" - : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) - : [x]"r"(x), "0"(*w0), "1"(*w1), "2"(*w2) - : "cc"); - -#else - *w0 += x; - word c1 = (*w0 < x); - *w1 += c1; - word c2 = (*w1 < c1); - *w2 += c2; -#endif - } - -/* -* Multiply-Add Accumulator -* (w2,w1,w0) += 2 * x * y -*/ -inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y) - { -#if defined(BOTAN_MP_USE_X86_32_ASM) - - word z0 = 0, z1 = 0; - - asm("mull %[y]" - : "=a"(z0),"=d"(z1) - : "a"(x), [y]"rm"(y) + : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2) + : [x] "r"(x), "0"(*w0), "1"(*w1), "2"(*w2) : "cc"); - asm(R"( +#else + *w0 += x; + word c1 = (*w0 < x); + *w1 += c1; + word c2 = (*w1 < c1); + *w2 += c2; +#endif +} + +/* + * Multiply-Add Accumulator + * (w2,w1,w0) += 2 * x * y + */ +inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y) { +#if defined(BOTAN_MP_USE_X86_32_ASM) + + word z0 = 0, z1 = 0; + + asm("mull %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc"); + + asm(R"( addl %[z0],%[w0] adcl %[z1],%[w1] adcl $0,%[w2] @@ -1859,20 +1671,17 @@ inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y) adcl %[z1],%[w1] adcl $0,%[w2] )" - : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) - : [z0]"r"(z0), [z1]"r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) - : "cc"); + : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2) + : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); #elif defined(BOTAN_MP_USE_X86_64_ASM) - word z0 = 0, z1 = 0; + word z0 = 0, z1 = 0; - asm("mulq %[y]" - : "=a"(z0),"=d"(z1) - : "a"(x), [y]"rm"(y) - : "cc"); + asm("mulq %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc"); - asm(R"( + asm(R"( addq %[z0],%[w0] adcq %[z1],%[w1] adcq $0,%[w2] @@ -1881,789 +1690,676 @@ inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y) adcq %[z1],%[w1] adcq $0,%[w2] )" - : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) - : [z0]"r"(z0), [z1]"r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) - : "cc"); + : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2) + : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); #else - word carry = 0; - x = word_madd2(x, y, &carry); - y = carry; + word carry = 0; + x = word_madd2(x, y, &carry); + y = carry; - word top = (y >> (BOTAN_MP_WORD_BITS-1)); - y <<= 1; - y |= (x >> (BOTAN_MP_WORD_BITS-1)); - x <<= 1; + word top = (y >> (BOTAN_MP_WORD_BITS - 1)); + y <<= 1; + y |= (x >> (BOTAN_MP_WORD_BITS - 1)); + x <<= 1; - carry = 0; - *w0 = word_add(*w0, x, &carry); - *w1 = word_add(*w1, y, &carry); - *w2 = word_add(*w2, top, &carry); + carry = 0; + *w0 = word_add(*w0, x, &carry); + *w1 = word_add(*w1, y, &carry); + *w2 = word_add(*w2, top, &carry); #endif - } +} #if defined(ASM) - #undef ASM - #undef DO_8_TIMES - #undef ADD_OR_SUBTRACT - #undef ADDSUB2_OP - #undef ADDSUB3_OP - #undef LINMUL_OP - #undef MULADD_OP +#undef ASM +#undef DO_8_TIMES +#undef ADD_OR_SUBTRACT +#undef ADDSUB2_OP +#undef ADDSUB3_OP +#undef LINMUL_OP +#undef MULADD_OP #endif -} +} // namespace Botan namespace Botan { const word MP_WORD_MAX = ~static_cast(0); /* -* If cond == 0, does nothing. -* If cond > 0, swaps x[0:size] with y[0:size] -* Runs in constant time -*/ -inline void bigint_cnd_swap(word cnd, word x[], word y[], size_t size) - { - const auto mask = CT::Mask::expand(cnd); + * If cond == 0, does nothing. + * If cond > 0, swaps x[0:size] with y[0:size] + * Runs in constant time + */ +inline void bigint_cnd_swap(word cnd, word x[], word y[], size_t size) { + const auto mask = CT::Mask::expand(cnd); - for(size_t i = 0; i != size; ++i) - { - const word a = x[i]; - const word b = y[i]; - x[i] = mask.select(b, a); - y[i] = mask.select(a, b); - } - } + for (size_t i = 0; i != size; ++i) { + const word a = x[i]; + const word b = y[i]; + x[i] = mask.select(b, a); + y[i] = mask.select(a, b); + } +} -inline word bigint_cnd_add(word cnd, word x[], word x_size, - const word y[], size_t y_size) - { - BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); +inline word bigint_cnd_add(word cnd, word x[], word x_size, const word y[], size_t y_size) { + BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); - const auto mask = CT::Mask::expand(cnd); + const auto mask = CT::Mask::expand(cnd); - word carry = 0; + word carry = 0; - const size_t blocks = y_size - (y_size % 8); - word z[8] = { 0 }; + const size_t blocks = y_size - (y_size % 8); + word z[8] = {0}; - for(size_t i = 0; i != blocks; i += 8) - { - carry = word8_add3(z, x + i, y + i, carry); - mask.select_n(x + i, z, x + i, 8); - } + for (size_t i = 0; i != blocks; i += 8) { + carry = word8_add3(z, x + i, y + i, carry); + mask.select_n(x + i, z, x + i, 8); + } - for(size_t i = blocks; i != y_size; ++i) - { - z[0] = word_add(x[i], y[i], &carry); - x[i] = mask.select(z[0], x[i]); - } + for (size_t i = blocks; i != y_size; ++i) { + z[0] = word_add(x[i], y[i], &carry); + x[i] = mask.select(z[0], x[i]); + } - for(size_t i = y_size; i != x_size; ++i) - { - z[0] = word_add(x[i], 0, &carry); - x[i] = mask.select(z[0], x[i]); - } + for (size_t i = y_size; i != x_size; ++i) { + z[0] = word_add(x[i], 0, &carry); + x[i] = mask.select(z[0], x[i]); + } - return mask.if_set_return(carry); - } + return mask.if_set_return(carry); +} /* -* If cond > 0 adds x[0:size] and y[0:size] and returns carry -* Runs in constant time -*/ -inline word bigint_cnd_add(word cnd, word x[], const word y[], size_t size) - { - return bigint_cnd_add(cnd, x, size, y, size); - } + * If cond > 0 adds x[0:size] and y[0:size] and returns carry + * Runs in constant time + */ +inline word bigint_cnd_add(word cnd, word x[], const word y[], size_t size) { + return bigint_cnd_add(cnd, x, size, y, size); +} /* -* If cond > 0 subtracts x[0:size] and y[0:size] and returns borrow -* Runs in constant time -*/ -inline word bigint_cnd_sub(word cnd, - word x[], size_t x_size, - const word y[], size_t y_size) - { - BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); + * If cond > 0 subtracts x[0:size] and y[0:size] and returns borrow + * Runs in constant time + */ +inline word bigint_cnd_sub(word cnd, word x[], size_t x_size, const word y[], size_t y_size) { + BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); - const auto mask = CT::Mask::expand(cnd); + const auto mask = CT::Mask::expand(cnd); - word carry = 0; + word carry = 0; - const size_t blocks = y_size - (y_size % 8); - word z[8] = { 0 }; + const size_t blocks = y_size - (y_size % 8); + word z[8] = {0}; - for(size_t i = 0; i != blocks; i += 8) - { - carry = word8_sub3(z, x + i, y + i, carry); - mask.select_n(x + i, z, x + i, 8); - } + for (size_t i = 0; i != blocks; i += 8) { + carry = word8_sub3(z, x + i, y + i, carry); + mask.select_n(x + i, z, x + i, 8); + } - for(size_t i = blocks; i != y_size; ++i) - { - z[0] = word_sub(x[i], y[i], &carry); - x[i] = mask.select(z[0], x[i]); - } + for (size_t i = blocks; i != y_size; ++i) { + z[0] = word_sub(x[i], y[i], &carry); + x[i] = mask.select(z[0], x[i]); + } - for(size_t i = y_size; i != x_size; ++i) - { - z[0] = word_sub(x[i], 0, &carry); - x[i] = mask.select(z[0], x[i]); - } + for (size_t i = y_size; i != x_size; ++i) { + z[0] = word_sub(x[i], 0, &carry); + x[i] = mask.select(z[0], x[i]); + } - return mask.if_set_return(carry); - } + return mask.if_set_return(carry); +} /* -* If cond > 0 adds x[0:size] and y[0:size] and returns carry -* Runs in constant time -*/ -inline word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size) - { - return bigint_cnd_sub(cnd, x, size, y, size); - } - + * If cond > 0 adds x[0:size] and y[0:size] and returns carry + * Runs in constant time + */ +inline word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size) { + return bigint_cnd_sub(cnd, x, size, y, size); +} /* -* Equivalent to -* bigint_cnd_add( mask, x, y, size); -* bigint_cnd_sub(~mask, x, y, size); -* -* Mask must be either 0 or all 1 bits -*/ -inline void bigint_cnd_add_or_sub(CT::Mask mask, word x[], const word y[], size_t size) - { - const size_t blocks = size - (size % 8); + * Equivalent to + * bigint_cnd_add( mask, x, y, size); + * bigint_cnd_sub(~mask, x, y, size); + * + * Mask must be either 0 or all 1 bits + */ +inline void bigint_cnd_add_or_sub(CT::Mask mask, word x[], const word y[], size_t size) { + const size_t blocks = size - (size % 8); - word carry = 0; - word borrow = 0; + word carry = 0; + word borrow = 0; - word t0[8] = { 0 }; - word t1[8] = { 0 }; + word t0[8] = {0}; + word t1[8] = {0}; - for(size_t i = 0; i != blocks; i += 8) - { - carry = word8_add3(t0, x + i, y + i, carry); - borrow = word8_sub3(t1, x + i, y + i, borrow); + for (size_t i = 0; i != blocks; i += 8) { + carry = word8_add3(t0, x + i, y + i, carry); + borrow = word8_sub3(t1, x + i, y + i, borrow); - for(size_t j = 0; j != 8; ++j) - x[i+j] = mask.select(t0[j], t1[j]); - } + for (size_t j = 0; j != 8; ++j) x[i + j] = mask.select(t0[j], t1[j]); + } - for(size_t i = blocks; i != size; ++i) - { - const word a = word_add(x[i], y[i], &carry); - const word s = word_sub(x[i], y[i], &borrow); + for (size_t i = blocks; i != size; ++i) { + const word a = word_add(x[i], y[i], &carry); + const word s = word_sub(x[i], y[i], &borrow); - x[i] = mask.select(a, s); - } - } + x[i] = mask.select(a, s); + } +} /* -* Equivalent to -* bigint_cnd_add( mask, x, size, y, size); -* bigint_cnd_sub(~mask, x, size, z, size); -* -* Mask must be either 0 or all 1 bits -* -* Returns the carry or borrow resp -*/ -inline word bigint_cnd_addsub(CT::Mask mask, word x[], - const word y[], const word z[], - size_t size) - { - const size_t blocks = size - (size % 8); + * Equivalent to + * bigint_cnd_add( mask, x, size, y, size); + * bigint_cnd_sub(~mask, x, size, z, size); + * + * Mask must be either 0 or all 1 bits + * + * Returns the carry or borrow resp + */ +inline word bigint_cnd_addsub(CT::Mask mask, word x[], const word y[], const word z[], + size_t size) { + const size_t blocks = size - (size % 8); - word carry = 0; - word borrow = 0; + word carry = 0; + word borrow = 0; - word t0[8] = { 0 }; - word t1[8] = { 0 }; + word t0[8] = {0}; + word t1[8] = {0}; - for(size_t i = 0; i != blocks; i += 8) - { - carry = word8_add3(t0, x + i, y + i, carry); - borrow = word8_sub3(t1, x + i, z + i, borrow); + for (size_t i = 0; i != blocks; i += 8) { + carry = word8_add3(t0, x + i, y + i, carry); + borrow = word8_sub3(t1, x + i, z + i, borrow); - for(size_t j = 0; j != 8; ++j) - x[i+j] = mask.select(t0[j], t1[j]); - } + for (size_t j = 0; j != 8; ++j) x[i + j] = mask.select(t0[j], t1[j]); + } - for(size_t i = blocks; i != size; ++i) - { - t0[0] = word_add(x[i], y[i], &carry); - t1[0] = word_sub(x[i], z[i], &borrow); - x[i] = mask.select(t0[0], t1[0]); - } + for (size_t i = blocks; i != size; ++i) { + t0[0] = word_add(x[i], y[i], &carry); + t1[0] = word_sub(x[i], z[i], &borrow); + x[i] = mask.select(t0[0], t1[0]); + } - return mask.select(carry, borrow); - } + return mask.select(carry, borrow); +} /* -* 2s complement absolute value -* If cond > 0 sets x to ~x + 1 -* Runs in constant time -*/ -inline void bigint_cnd_abs(word cnd, word x[], size_t size) - { - const auto mask = CT::Mask::expand(cnd); + * 2s complement absolute value + * If cond > 0 sets x to ~x + 1 + * Runs in constant time + */ +inline void bigint_cnd_abs(word cnd, word x[], size_t size) { + const auto mask = CT::Mask::expand(cnd); - word carry = mask.if_set_return(1); - for(size_t i = 0; i != size; ++i) - { - const word z = word_add(~x[i], 0, &carry); - x[i] = mask.select(z, x[i]); - } - } + word carry = mask.if_set_return(1); + for (size_t i = 0; i != size; ++i) { + const word z = word_add(~x[i], 0, &carry); + x[i] = mask.select(z, x[i]); + } +} /** -* Two operand addition with carry out -*/ -inline word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size) - { - word carry = 0; + * Two operand addition with carry out + */ +inline word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size) { + word carry = 0; - BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); + BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); - const size_t blocks = y_size - (y_size % 8); + const size_t blocks = y_size - (y_size % 8); - for(size_t i = 0; i != blocks; i += 8) - carry = word8_add2(x + i, y + i, carry); + for (size_t i = 0; i != blocks; i += 8) carry = word8_add2(x + i, y + i, carry); - for(size_t i = blocks; i != y_size; ++i) - x[i] = word_add(x[i], y[i], &carry); + for (size_t i = blocks; i != y_size; ++i) x[i] = word_add(x[i], y[i], &carry); - for(size_t i = y_size; i != x_size; ++i) - x[i] = word_add(x[i], 0, &carry); + for (size_t i = y_size; i != x_size; ++i) x[i] = word_add(x[i], 0, &carry); - return carry; - } + return carry; +} /** -* Three operand addition with carry out -*/ -inline word bigint_add3_nc(word z[], - const word x[], size_t x_size, - const word y[], size_t y_size) - { - if(x_size < y_size) - { return bigint_add3_nc(z, y, y_size, x, x_size); } + * Three operand addition with carry out + */ +inline word bigint_add3_nc(word z[], const word x[], size_t x_size, const word y[], size_t y_size) { + if (x_size < y_size) { + return bigint_add3_nc(z, y, y_size, x, x_size); + } - word carry = 0; + word carry = 0; - const size_t blocks = y_size - (y_size % 8); + const size_t blocks = y_size - (y_size % 8); - for(size_t i = 0; i != blocks; i += 8) - carry = word8_add3(z + i, x + i, y + i, carry); + for (size_t i = 0; i != blocks; i += 8) carry = word8_add3(z + i, x + i, y + i, carry); - for(size_t i = blocks; i != y_size; ++i) - z[i] = word_add(x[i], y[i], &carry); + for (size_t i = blocks; i != y_size; ++i) z[i] = word_add(x[i], y[i], &carry); - for(size_t i = y_size; i != x_size; ++i) - z[i] = word_add(x[i], 0, &carry); + for (size_t i = y_size; i != x_size; ++i) z[i] = word_add(x[i], 0, &carry); - return carry; - } + return carry; +} /** -* Two operand addition -* @param x the first operand (and output) -* @param x_size size of x -* @param y the second operand -* @param y_size size of y (must be >= x_size) -*/ -inline void bigint_add2(word x[], size_t x_size, - const word y[], size_t y_size) - { - x[x_size] += bigint_add2_nc(x, x_size, y, y_size); - } + * Two operand addition + * @param x the first operand (and output) + * @param x_size size of x + * @param y the second operand + * @param y_size size of y (must be >= x_size) + */ +inline void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size) { + x[x_size] += bigint_add2_nc(x, x_size, y, y_size); +} /** -* Three operand addition -*/ -inline void bigint_add3(word z[], - const word x[], size_t x_size, - const word y[], size_t y_size) - { - z[x_size > y_size ? x_size : y_size] += - bigint_add3_nc(z, x, x_size, y, y_size); - } + * Three operand addition + */ +inline void bigint_add3(word z[], const word x[], size_t x_size, const word y[], size_t y_size) { + z[x_size > y_size ? x_size : y_size] += bigint_add3_nc(z, x, x_size, y, y_size); +} /** -* Two operand subtraction -*/ -inline word bigint_sub2(word x[], size_t x_size, - const word y[], size_t y_size) - { - word borrow = 0; + * Two operand subtraction + */ +inline word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size) { + word borrow = 0; - BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); + BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); - const size_t blocks = y_size - (y_size % 8); + const size_t blocks = y_size - (y_size % 8); - for(size_t i = 0; i != blocks; i += 8) - borrow = word8_sub2(x + i, y + i, borrow); + for (size_t i = 0; i != blocks; i += 8) borrow = word8_sub2(x + i, y + i, borrow); - for(size_t i = blocks; i != y_size; ++i) - x[i] = word_sub(x[i], y[i], &borrow); + for (size_t i = blocks; i != y_size; ++i) x[i] = word_sub(x[i], y[i], &borrow); - for(size_t i = y_size; i != x_size; ++i) - x[i] = word_sub(x[i], 0, &borrow); + for (size_t i = y_size; i != x_size; ++i) x[i] = word_sub(x[i], 0, &borrow); - return borrow; - } + return borrow; +} /** -* Two operand subtraction, x = y - x; assumes y >= x -*/ -inline void bigint_sub2_rev(word x[], const word y[], size_t y_size) - { - word borrow = 0; + * Two operand subtraction, x = y - x; assumes y >= x + */ +inline void bigint_sub2_rev(word x[], const word y[], size_t y_size) { + word borrow = 0; - const size_t blocks = y_size - (y_size % 8); + const size_t blocks = y_size - (y_size % 8); - for(size_t i = 0; i != blocks; i += 8) - borrow = word8_sub2_rev(x + i, y + i, borrow); + for (size_t i = 0; i != blocks; i += 8) borrow = word8_sub2_rev(x + i, y + i, borrow); - for(size_t i = blocks; i != y_size; ++i) - x[i] = word_sub(y[i], x[i], &borrow); + for (size_t i = blocks; i != y_size; ++i) x[i] = word_sub(y[i], x[i], &borrow); - BOTAN_ASSERT(borrow == 0, "y must be greater than x"); - } + BOTAN_ASSERT(borrow == 0, "y must be greater than x"); +} /** -* Three operand subtraction -*/ -inline word bigint_sub3(word z[], - const word x[], size_t x_size, - const word y[], size_t y_size) - { - word borrow = 0; + * Three operand subtraction + */ +inline word bigint_sub3(word z[], const word x[], size_t x_size, const word y[], size_t y_size) { + word borrow = 0; - BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); + BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); - const size_t blocks = y_size - (y_size % 8); + const size_t blocks = y_size - (y_size % 8); - for(size_t i = 0; i != blocks; i += 8) - borrow = word8_sub3(z + i, x + i, y + i, borrow); + for (size_t i = 0; i != blocks; i += 8) borrow = word8_sub3(z + i, x + i, y + i, borrow); - for(size_t i = blocks; i != y_size; ++i) - z[i] = word_sub(x[i], y[i], &borrow); + for (size_t i = blocks; i != y_size; ++i) z[i] = word_sub(x[i], y[i], &borrow); - for(size_t i = y_size; i != x_size; ++i) - z[i] = word_sub(x[i], 0, &borrow); + for (size_t i = y_size; i != x_size; ++i) z[i] = word_sub(x[i], 0, &borrow); - return borrow; - } + return borrow; +} /** -* Return abs(x-y), ie if x >= y, then compute z = x - y -* Otherwise compute z = y - x -* No borrow is possible since the result is always >= 0 -* -* Returns ~0 if x >= y or 0 if x < y -* @param z output array of at least N words -* @param x input array of N words -* @param y input array of N words -* @param N length of x and y -* @param ws array of at least 2*N words -*/ -inline CT::Mask -bigint_sub_abs(word z[], - const word x[], const word y[], size_t N, - word ws[]) - { - // Subtract in both direction then conditional copy out the result + * Return abs(x-y), ie if x >= y, then compute z = x - y + * Otherwise compute z = y - x + * No borrow is possible since the result is always >= 0 + * + * Returns ~0 if x >= y or 0 if x < y + * @param z output array of at least N words + * @param x input array of N words + * @param y input array of N words + * @param N length of x and y + * @param ws array of at least 2*N words + */ +inline CT::Mask bigint_sub_abs(word z[], const word x[], const word y[], size_t N, + word ws[]) { + // Subtract in both direction then conditional copy out the result - word* ws0 = ws; - word* ws1 = ws + N; + word* ws0 = ws; + word* ws1 = ws + N; - word borrow0 = 0; - word borrow1 = 0; + word borrow0 = 0; + word borrow1 = 0; - const size_t blocks = N - (N % 8); + const size_t blocks = N - (N % 8); - for(size_t i = 0; i != blocks; i += 8) - { - borrow0 = word8_sub3(ws0 + i, x + i, y + i, borrow0); - borrow1 = word8_sub3(ws1 + i, y + i, x + i, borrow1); - } + for (size_t i = 0; i != blocks; i += 8) { + borrow0 = word8_sub3(ws0 + i, x + i, y + i, borrow0); + borrow1 = word8_sub3(ws1 + i, y + i, x + i, borrow1); + } - for(size_t i = blocks; i != N; ++i) - { - ws0[i] = word_sub(x[i], y[i], &borrow0); - ws1[i] = word_sub(y[i], x[i], &borrow1); - } + for (size_t i = blocks; i != N; ++i) { + ws0[i] = word_sub(x[i], y[i], &borrow0); + ws1[i] = word_sub(y[i], x[i], &borrow1); + } - return CT::conditional_copy_mem(borrow0, z, ws1, ws0, N); - } + return CT::conditional_copy_mem(borrow0, z, ws1, ws0, N); +} /* -* Shift Operations -*/ -inline void bigint_shl1(word x[], size_t x_size, size_t x_words, - size_t word_shift, size_t bit_shift) - { - copy_mem(x + word_shift, x, x_words); - clear_mem(x, word_shift); + * Shift Operations + */ +inline void bigint_shl1(word x[], size_t x_size, size_t x_words, size_t word_shift, + size_t bit_shift) { + copy_mem(x + word_shift, x, x_words); + clear_mem(x, word_shift); - const auto carry_mask = CT::Mask::expand(bit_shift); - const size_t carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift); + const auto carry_mask = CT::Mask::expand(bit_shift); + const size_t carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift); - word carry = 0; - for(size_t i = word_shift; i != x_size; ++i) - { - const word w = x[i]; - x[i] = (w << bit_shift) | carry; - carry = carry_mask.if_set_return(w >> carry_shift); - } - } + word carry = 0; + for (size_t i = word_shift; i != x_size; ++i) { + const word w = x[i]; + x[i] = (w << bit_shift) | carry; + carry = carry_mask.if_set_return(w >> carry_shift); + } +} -inline void bigint_shr1(word x[], size_t x_size, - size_t word_shift, size_t bit_shift) - { - const size_t top = x_size >= word_shift ? (x_size - word_shift) : 0; +inline void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) { + const size_t top = x_size >= word_shift ? (x_size - word_shift) : 0; - copy_mem(x, x + word_shift, top); - clear_mem(x + top, std::min(word_shift, x_size)); + copy_mem(x, x + word_shift, top); + clear_mem(x + top, std::min(word_shift, x_size)); - const auto carry_mask = CT::Mask::expand(bit_shift); - const size_t carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift); + const auto carry_mask = CT::Mask::expand(bit_shift); + const size_t carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift); - word carry = 0; + word carry = 0; - for(size_t i = 0; i != top; ++i) - { - const word w = x[top - i - 1]; - x[top-i-1] = (w >> bit_shift) | carry; - carry = carry_mask.if_set_return(w << carry_shift); - } - } + for (size_t i = 0; i != top; ++i) { + const word w = x[top - i - 1]; + x[top - i - 1] = (w >> bit_shift) | carry; + carry = carry_mask.if_set_return(w << carry_shift); + } +} -inline void bigint_shl2(word y[], const word x[], size_t x_size, - size_t word_shift, size_t bit_shift) - { - copy_mem(y + word_shift, x, x_size); +inline void bigint_shl2(word y[], const word x[], size_t x_size, size_t word_shift, + size_t bit_shift) { + copy_mem(y + word_shift, x, x_size); - const auto carry_mask = CT::Mask::expand(bit_shift); - const size_t carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift); + const auto carry_mask = CT::Mask::expand(bit_shift); + const size_t carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift); - word carry = 0; - for(size_t i = word_shift; i != x_size + word_shift + 1; ++i) - { - const word w = y[i]; - y[i] = (w << bit_shift) | carry; - carry = carry_mask.if_set_return(w >> carry_shift); - } - } + word carry = 0; + for (size_t i = word_shift; i != x_size + word_shift + 1; ++i) { + const word w = y[i]; + y[i] = (w << bit_shift) | carry; + carry = carry_mask.if_set_return(w >> carry_shift); + } +} -inline void bigint_shr2(word y[], const word x[], size_t x_size, - size_t word_shift, size_t bit_shift) - { - const size_t new_size = x_size < word_shift ? 0 : (x_size - word_shift); +inline void bigint_shr2(word y[], const word x[], size_t x_size, size_t word_shift, + size_t bit_shift) { + const size_t new_size = x_size < word_shift ? 0 : (x_size - word_shift); - copy_mem(y, x + word_shift, new_size); + copy_mem(y, x + word_shift, new_size); - const auto carry_mask = CT::Mask::expand(bit_shift); - const size_t carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift); + const auto carry_mask = CT::Mask::expand(bit_shift); + const size_t carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift); - word carry = 0; - for(size_t i = new_size; i > 0; --i) - { - word w = y[i-1]; - y[i-1] = (w >> bit_shift) | carry; - carry = carry_mask.if_set_return(w << carry_shift); - } - } + word carry = 0; + for (size_t i = new_size; i > 0; --i) { + word w = y[i - 1]; + y[i - 1] = (w >> bit_shift) | carry; + carry = carry_mask.if_set_return(w << carry_shift); + } +} /* -* Linear Multiply - returns the carry -*/ -inline word BOTAN_WARN_UNUSED_RESULT bigint_linmul2(word x[], size_t x_size, word y) - { - const size_t blocks = x_size - (x_size % 8); + * Linear Multiply - returns the carry + */ +inline word BOTAN_WARN_UNUSED_RESULT bigint_linmul2(word x[], size_t x_size, word y) { + const size_t blocks = x_size - (x_size % 8); - word carry = 0; + word carry = 0; - for(size_t i = 0; i != blocks; i += 8) - carry = word8_linmul2(x + i, y, carry); + for (size_t i = 0; i != blocks; i += 8) carry = word8_linmul2(x + i, y, carry); - for(size_t i = blocks; i != x_size; ++i) - x[i] = word_madd2(x[i], y, &carry); + for (size_t i = blocks; i != x_size; ++i) x[i] = word_madd2(x[i], y, &carry); - return carry; - } + return carry; +} -inline void bigint_linmul3(word z[], const word x[], size_t x_size, word y) - { - const size_t blocks = x_size - (x_size % 8); +inline void bigint_linmul3(word z[], const word x[], size_t x_size, word y) { + const size_t blocks = x_size - (x_size % 8); - word carry = 0; + word carry = 0; - for(size_t i = 0; i != blocks; i += 8) - carry = word8_linmul3(z + i, x + i, y, carry); + for (size_t i = 0; i != blocks; i += 8) carry = word8_linmul3(z + i, x + i, y, carry); - for(size_t i = blocks; i != x_size; ++i) - z[i] = word_madd2(x[i], y, &carry); + for (size_t i = blocks; i != x_size; ++i) z[i] = word_madd2(x[i], y, &carry); - z[x_size] = carry; - } + z[x_size] = carry; +} /** -* Compare x and y -* Return -1 if x < y -* Return 0 if x == y -* Return 1 if x > y -*/ -inline int32_t bigint_cmp(const word x[], size_t x_size, - const word y[], size_t y_size) - { - static_assert(sizeof(word) >= sizeof(uint32_t), "Size assumption"); + * Compare x and y + * Return -1 if x < y + * Return 0 if x == y + * Return 1 if x > y + */ +inline int32_t bigint_cmp(const word x[], size_t x_size, const word y[], size_t y_size) { + static_assert(sizeof(word) >= sizeof(uint32_t), "Size assumption"); - const word LT = static_cast(-1); - const word EQ = 0; - const word GT = 1; + const word LT = static_cast(-1); + const word EQ = 0; + const word GT = 1; - const size_t common_elems = std::min(x_size, y_size); + const size_t common_elems = std::min(x_size, y_size); - word result = EQ; // until found otherwise + word result = EQ; // until found otherwise - for(size_t i = 0; i != common_elems; i++) - { - const auto is_eq = CT::Mask::is_equal(x[i], y[i]); - const auto is_lt = CT::Mask::is_lt(x[i], y[i]); + for (size_t i = 0; i != common_elems; i++) { + const auto is_eq = CT::Mask::is_equal(x[i], y[i]); + const auto is_lt = CT::Mask::is_lt(x[i], y[i]); - result = is_eq.select(result, is_lt.select(LT, GT)); - } + result = is_eq.select(result, is_lt.select(LT, GT)); + } - if(x_size < y_size) - { - word mask = 0; - for(size_t i = x_size; i != y_size; i++) - mask |= y[i]; + if (x_size < y_size) { + word mask = 0; + for (size_t i = x_size; i != y_size; i++) mask |= y[i]; - // If any bits were set in high part of y, then x < y - result = CT::Mask::is_zero(mask).select(result, LT); - } - else if(y_size < x_size) - { - word mask = 0; - for(size_t i = y_size; i != x_size; i++) - mask |= x[i]; + // If any bits were set in high part of y, then x < y + result = CT::Mask::is_zero(mask).select(result, LT); + } else if (y_size < x_size) { + word mask = 0; + for (size_t i = y_size; i != x_size; i++) mask |= x[i]; - // If any bits were set in high part of x, then x > y - result = CT::Mask::is_zero(mask).select(result, GT); - } + // If any bits were set in high part of x, then x > y + result = CT::Mask::is_zero(mask).select(result, GT); + } - CT::unpoison(result); - BOTAN_DEBUG_ASSERT(result == LT || result == GT || result == EQ); - return static_cast(result); - } + CT::unpoison(result); + BOTAN_DEBUG_ASSERT(result == LT || result == GT || result == EQ); + return static_cast(result); +} /** -* Compare x and y -* Return ~0 if x[0:x_size] < y[0:y_size] or 0 otherwise -* If lt_or_equal is true, returns ~0 also for x == y -*/ -inline CT::Mask -bigint_ct_is_lt(const word x[], size_t x_size, - const word y[], size_t y_size, - bool lt_or_equal = false) - { - const size_t common_elems = std::min(x_size, y_size); + * Compare x and y + * Return ~0 if x[0:x_size] < y[0:y_size] or 0 otherwise + * If lt_or_equal is true, returns ~0 also for x == y + */ +inline CT::Mask bigint_ct_is_lt(const word x[], size_t x_size, const word y[], size_t y_size, + bool lt_or_equal = false) { + const size_t common_elems = std::min(x_size, y_size); - auto is_lt = CT::Mask::expand(lt_or_equal); + auto is_lt = CT::Mask::expand(lt_or_equal); - for(size_t i = 0; i != common_elems; i++) - { - const auto eq = CT::Mask::is_equal(x[i], y[i]); - const auto lt = CT::Mask::is_lt(x[i], y[i]); - is_lt = eq.select_mask(is_lt, lt); - } + for (size_t i = 0; i != common_elems; i++) { + const auto eq = CT::Mask::is_equal(x[i], y[i]); + const auto lt = CT::Mask::is_lt(x[i], y[i]); + is_lt = eq.select_mask(is_lt, lt); + } - if(x_size < y_size) - { - word mask = 0; - for(size_t i = x_size; i != y_size; i++) - mask |= y[i]; - // If any bits were set in high part of y, then is_lt should be forced true - is_lt |= CT::Mask::expand(mask); - } - else if(y_size < x_size) - { - word mask = 0; - for(size_t i = y_size; i != x_size; i++) - mask |= x[i]; + if (x_size < y_size) { + word mask = 0; + for (size_t i = x_size; i != y_size; i++) mask |= y[i]; + // If any bits were set in high part of y, then is_lt should be forced true + is_lt |= CT::Mask::expand(mask); + } else if (y_size < x_size) { + word mask = 0; + for (size_t i = y_size; i != x_size; i++) mask |= x[i]; - // If any bits were set in high part of x, then is_lt should be false - is_lt &= CT::Mask::is_zero(mask); - } + // If any bits were set in high part of x, then is_lt should be false + is_lt &= CT::Mask::is_zero(mask); + } - return is_lt; - } + return is_lt; +} -inline CT::Mask -bigint_ct_is_eq(const word x[], size_t x_size, - const word y[], size_t y_size) - { - const size_t common_elems = std::min(x_size, y_size); +inline CT::Mask bigint_ct_is_eq(const word x[], size_t x_size, const word y[], + size_t y_size) { + const size_t common_elems = std::min(x_size, y_size); - word diff = 0; + word diff = 0; - for(size_t i = 0; i != common_elems; i++) - { - diff |= (x[i] ^ y[i]); - } + for (size_t i = 0; i != common_elems; i++) { + diff |= (x[i] ^ y[i]); + } - // If any bits were set in high part of x/y, then they are not equal - if(x_size < y_size) - { - for(size_t i = x_size; i != y_size; i++) - diff |= y[i]; - } - else if(y_size < x_size) - { - for(size_t i = y_size; i != x_size; i++) - diff |= x[i]; - } + // If any bits were set in high part of x/y, then they are not equal + if (x_size < y_size) { + for (size_t i = x_size; i != y_size; i++) diff |= y[i]; + } else if (y_size < x_size) { + for (size_t i = y_size; i != x_size; i++) diff |= x[i]; + } - return CT::Mask::is_zero(diff); - } + return CT::Mask::is_zero(diff); +} /** -* Set z to abs(x-y), ie if x >= y, then compute z = x - y -* Otherwise compute z = y - x -* No borrow is possible since the result is always >= 0 -* -* Return the relative size of x vs y (-1, 0, 1) -* -* @param z output array of max(x_size,y_size) words -* @param x input param -* @param x_size length of x -* @param y input param -* @param y_size length of y -*/ -inline int32_t -bigint_sub_abs(word z[], - const word x[], size_t x_size, - const word y[], size_t y_size) - { - const int32_t relative_size = bigint_cmp(x, x_size, y, y_size); + * Set z to abs(x-y), ie if x >= y, then compute z = x - y + * Otherwise compute z = y - x + * No borrow is possible since the result is always >= 0 + * + * Return the relative size of x vs y (-1, 0, 1) + * + * @param z output array of max(x_size,y_size) words + * @param x input param + * @param x_size length of x + * @param y input param + * @param y_size length of y + */ +inline int32_t bigint_sub_abs(word z[], const word x[], size_t x_size, const word y[], + size_t y_size) { + const int32_t relative_size = bigint_cmp(x, x_size, y, y_size); - // Swap if relative_size == -1 - CT::conditional_swap_ptr(relative_size < 0, x, y); - CT::conditional_swap(relative_size < 0, x_size, y_size); + // Swap if relative_size == -1 + CT::conditional_swap_ptr(relative_size < 0, x, y); + CT::conditional_swap(relative_size < 0, x_size, y_size); - /* - * We know at this point that x >= y so if y_size is larger than - * x_size, we are guaranteed they are just leading zeros which can - * be ignored - */ - y_size = std::min(x_size, y_size); + /* + * We know at this point that x >= y so if y_size is larger than + * x_size, we are guaranteed they are just leading zeros which can + * be ignored + */ + y_size = std::min(x_size, y_size); - bigint_sub3(z, x, x_size, y, y_size); + bigint_sub3(z, x, x_size, y, y_size); - return relative_size; - } + return relative_size; +} /** -* Set t to t-s modulo mod -* -* @param t first integer -* @param s second integer -* @param mod the modulus -* @param mod_sw size of t, s, and mod -* @param ws workspace of size mod_sw -*/ -inline void -bigint_mod_sub(word t[], const word s[], const word mod[], size_t mod_sw, word ws[]) - { - // is t < s or not? - const auto is_lt = bigint_ct_is_lt(t, mod_sw, s, mod_sw); + * Set t to t-s modulo mod + * + * @param t first integer + * @param s second integer + * @param mod the modulus + * @param mod_sw size of t, s, and mod + * @param ws workspace of size mod_sw + */ +inline void bigint_mod_sub(word t[], const word s[], const word mod[], size_t mod_sw, word ws[]) { + // is t < s or not? + const auto is_lt = bigint_ct_is_lt(t, mod_sw, s, mod_sw); - // ws = p - s - const word borrow = bigint_sub3(ws, mod, mod_sw, s, mod_sw); + // ws = p - s + const word borrow = bigint_sub3(ws, mod, mod_sw, s, mod_sw); - // Compute either (t - s) or (t + (p - s)) depending on mask - const word carry = bigint_cnd_addsub(is_lt, t, ws, s, mod_sw); + // Compute either (t - s) or (t + (p - s)) depending on mask + const word carry = bigint_cnd_addsub(is_lt, t, ws, s, mod_sw); - BOTAN_DEBUG_ASSERT(borrow == 0 && carry == 0); - BOTAN_UNUSED(carry, borrow); - } + BOTAN_DEBUG_ASSERT(borrow == 0 && carry == 0); + BOTAN_UNUSED(carry, borrow); +} -template -inline void bigint_mod_sub_n(word t[], const word s[], const word mod[], word ws[]) - { - // is t < s or not? - const auto is_lt = bigint_ct_is_lt(t, N, s, N); +template +inline void bigint_mod_sub_n(word t[], const word s[], const word mod[], word ws[]) { + // is t < s or not? + const auto is_lt = bigint_ct_is_lt(t, N, s, N); - // ws = p - s - const word borrow = bigint_sub3(ws, mod, N, s, N); + // ws = p - s + const word borrow = bigint_sub3(ws, mod, N, s, N); - // Compute either (t - s) or (t + (p - s)) depending on mask - const word carry = bigint_cnd_addsub(is_lt, t, ws, s, N); + // Compute either (t - s) or (t + (p - s)) depending on mask + const word carry = bigint_cnd_addsub(is_lt, t, ws, s, N); - BOTAN_DEBUG_ASSERT(borrow == 0 && carry == 0); - BOTAN_UNUSED(carry, borrow); - } + BOTAN_DEBUG_ASSERT(borrow == 0 && carry == 0); + BOTAN_UNUSED(carry, borrow); +} /** -* Compute ((n1<(n1) << BOTAN_MP_WORD_BITS) | n0) / d; + return ((static_cast(n1) << BOTAN_MP_WORD_BITS) | n0) / d; #else - word high = n1 % d; - word quotient = 0; + word high = n1 % d; + word quotient = 0; - for(size_t i = 0; i != BOTAN_MP_WORD_BITS; ++i) - { - const word high_top_bit = high >> (BOTAN_MP_WORD_BITS-1); + for (size_t i = 0; i != BOTAN_MP_WORD_BITS; ++i) { + const word high_top_bit = high >> (BOTAN_MP_WORD_BITS - 1); - high <<= 1; - high |= (n0 >> (BOTAN_MP_WORD_BITS-1-i)) & 1; - quotient <<= 1; + high <<= 1; + high |= (n0 >> (BOTAN_MP_WORD_BITS - 1 - i)) & 1; + quotient <<= 1; - if(high_top_bit || high >= d) - { - high -= d; - quotient |= 1; - } - } + if (high_top_bit || high >= d) { + high -= d; + quotient |= 1; + } + } - return quotient; + return quotient; #endif - } +} /** -* Compute ((n1<(n1) << BOTAN_MP_WORD_BITS) | n0) % d; + return ((static_cast(n1) << BOTAN_MP_WORD_BITS) | n0) % d; #else - word z = bigint_divop(n1, n0, d); - word dummy = 0; - z = word_madd2(z, d, &dummy); - return (n0-z); + word z = bigint_divop(n1, n0, d); + word dummy = 0; + z = word_madd2(z, d, &dummy); + return (n0 - z); #endif - } +} /* -* Comba Multiplication / Squaring -*/ + * Comba Multiplication / Squaring + */ void bigint_comba_mul4(word z[8], const word x[4], const word y[4]); void bigint_comba_mul6(word z[12], const word x[6], const word y[6]); void bigint_comba_mul8(word z[16], const word x[8], const word y[8]); @@ -2689,35 +2385,29 @@ void bigint_comba_sqr24(word out[48], const word in[24]); * @param workspace array of at least 2*(p_size+1) words * @param ws_size size of workspace in words */ -void bigint_monty_redc(word z[], - const word p[], size_t p_size, - word p_dash, - word workspace[], +void bigint_monty_redc(word z[], const word p[], size_t p_size, word p_dash, word workspace[], size_t ws_size); /* -* High Level Multiplication/Squaring Interfaces -*/ + * High Level Multiplication/Squaring Interfaces + */ -void bigint_mul(word z[], size_t z_size, - const word x[], size_t x_size, size_t x_sw, - const word y[], size_t y_size, size_t y_sw, +void bigint_mul(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, const word y[], + size_t y_size, size_t y_sw, word workspace[], size_t ws_size); + +void bigint_sqr(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, word workspace[], size_t ws_size); -void bigint_sqr(word z[], size_t z_size, - const word x[], size_t x_size, size_t x_sw, - word workspace[], size_t ws_size); - -} +} // namespace Botan namespace Botan { /* -* Each of these functions makes the following assumptions: -* -* z_size >= 2*(p_size + 1) -* ws_size >= z_size -*/ + * Each of these functions makes the following assumptions: + * + * z_size >= 2*(p_size + 1) + * ws_size >= z_size + */ void bigint_monty_redc_4(word z[], const word p[], word p_dash, word ws[]); void bigint_monty_redc_6(word z[], const word p[], word p_dash, word ws[]); @@ -2726,511 +2416,490 @@ void bigint_monty_redc_16(word z[], const word p[], word p_dash, word ws[]); void bigint_monty_redc_24(word z[], const word p[], word p_dash, word ws[]); void bigint_monty_redc_32(word z[], const word p[], word p_dash, word ws[]); - -} +} // namespace Botan namespace Botan { namespace OS { /* -* This header is internal (not installed) and these functions are not -* intended to be called by applications. However they are given public -* visibility (using BOTAN_TEST_API macro) for the tests. This also probably -* allows them to be overridden by the application on ELF systems, but -* this hasn't been tested. -*/ + * This header is internal (not installed) and these functions are not + * intended to be called by applications. However they are given public + * visibility (using BOTAN_TEST_API macro) for the tests. This also probably + * allows them to be overridden by the application on ELF systems, but + * this hasn't been tested. + */ /** -* @return process ID assigned by the operating system. -* On Unix and Windows systems, this always returns a result -* On IncludeOS it returns 0 since there is no process ID to speak of -* in a unikernel. -*/ + * @return process ID assigned by the operating system. + * On Unix and Windows systems, this always returns a result + * On IncludeOS it returns 0 since there is no process ID to speak of + * in a unikernel. + */ uint32_t BOTAN_TEST_API get_process_id(); /** -* Test if we are currently running with elevated permissions -* eg setuid, setgid, or with POSIX caps set. -*/ + * Test if we are currently running with elevated permissions + * eg setuid, setgid, or with POSIX caps set. + */ bool running_in_privileged_state(); /** -* @return CPU processor clock, if available -* -* On Windows, calls QueryPerformanceCounter. -* -* Under GCC or Clang on supported platforms the hardware cycle counter is queried. -* Currently supported processors are x86, PPC, Alpha, SPARC, IA-64, S/390x, and HP-PA. -* If no CPU cycle counter is available on this system, returns zero. -*/ + * @return CPU processor clock, if available + * + * On Windows, calls QueryPerformanceCounter. + * + * Under GCC or Clang on supported platforms the hardware cycle counter is queried. + * Currently supported processors are x86, PPC, Alpha, SPARC, IA-64, S/390x, and HP-PA. + * If no CPU cycle counter is available on this system, returns zero. + */ uint64_t BOTAN_TEST_API get_cpu_cycle_counter(); size_t BOTAN_TEST_API get_cpu_total(); size_t BOTAN_TEST_API get_cpu_available(); /** -* Return the ELF auxiliary vector cooresponding to the given ID. -* This only makes sense on Unix-like systems and is currently -* only supported on Linux, Android, and FreeBSD. -* -* Returns zero if not supported on the current system or if -* the id provided is not known. -*/ + * Return the ELF auxiliary vector cooresponding to the given ID. + * This only makes sense on Unix-like systems and is currently + * only supported on Linux, Android, and FreeBSD. + * + * Returns zero if not supported on the current system or if + * the id provided is not known. + */ unsigned long get_auxval(unsigned long id); /* -* @return best resolution timestamp available -* -* The epoch and update rate of this clock is arbitrary and depending -* on the hardware it may not tick at a constant rate. -* -* Uses hardware cycle counter, if available. -* On POSIX platforms clock_gettime is used with a monotonic timer -* As a final fallback std::chrono::high_resolution_clock is used. -*/ + * @return best resolution timestamp available + * + * The epoch and update rate of this clock is arbitrary and depending + * on the hardware it may not tick at a constant rate. + * + * Uses hardware cycle counter, if available. + * On POSIX platforms clock_gettime is used with a monotonic timer + * As a final fallback std::chrono::high_resolution_clock is used. + */ uint64_t BOTAN_TEST_API get_high_resolution_clock(); /** -* @return system clock (reflecting wall clock) with best resolution -* available, normalized to nanoseconds resolution. -*/ + * @return system clock (reflecting wall clock) with best resolution + * available, normalized to nanoseconds resolution. + */ uint64_t BOTAN_TEST_API get_system_timestamp_ns(); /** -* @return maximum amount of memory (in bytes) Botan could/should -* hyptothetically allocate for the memory poool. Reads environment -* variable "BOTAN_MLOCK_POOL_SIZE", set to "0" to disable pool. -*/ + * @return maximum amount of memory (in bytes) Botan could/should + * hyptothetically allocate for the memory poool. Reads environment + * variable "BOTAN_MLOCK_POOL_SIZE", set to "0" to disable pool. + */ size_t get_memory_locking_limit(); /** -* Return the size of a memory page, if that can be derived on the -* current system. Otherwise returns some default value (eg 4096) -*/ + * Return the size of a memory page, if that can be derived on the + * current system. Otherwise returns some default value (eg 4096) + */ size_t system_page_size(); /** -* Read the value of an environment variable. Return nullptr if -* no such variable is set. If the process seems to be running in -* a privileged state (such as setuid) then always returns nullptr, -* similiar to glibc's secure_getenv. -*/ + * Read the value of an environment variable. Return nullptr if + * no such variable is set. If the process seems to be running in + * a privileged state (such as setuid) then always returns nullptr, + * similiar to glibc's secure_getenv. + */ const char* read_env_variable(const std::string& var_name); /** -* Read the value of an environment variable and convert it to an -* integer. If not set or conversion fails, returns the default value. -* -* If the process seems to be running in a privileged state (such as setuid) -* then always returns nullptr, similiar to glibc's secure_getenv. -*/ + * Read the value of an environment variable and convert it to an + * integer. If not set or conversion fails, returns the default value. + * + * If the process seems to be running in a privileged state (such as setuid) + * then always returns nullptr, similiar to glibc's secure_getenv. + */ size_t read_env_variable_sz(const std::string& var_name, size_t def_value = 0); /** -* Request count pages of RAM which are locked into memory using mlock, -* VirtualLock, or some similar OS specific API. Free it with free_locked_pages. -* -* Returns an empty list on failure. This function is allowed to return fewer -* than count pages. -* -* The contents of the allocated pages are undefined. -* -* Each page is preceded by and followed by a page which is marked -* as noaccess, such that accessing it will cause a crash. This turns -* out of bound reads/writes into crash events. -* -* @param count requested number of locked pages -*/ + * Request count pages of RAM which are locked into memory using mlock, + * VirtualLock, or some similar OS specific API. Free it with free_locked_pages. + * + * Returns an empty list on failure. This function is allowed to return fewer + * than count pages. + * + * The contents of the allocated pages are undefined. + * + * Each page is preceded by and followed by a page which is marked + * as noaccess, such that accessing it will cause a crash. This turns + * out of bound reads/writes into crash events. + * + * @param count requested number of locked pages + */ std::vector allocate_locked_pages(size_t count); /** -* Free memory allocated by allocate_locked_pages -* @param pages a list of pages returned by allocate_locked_pages -*/ + * Free memory allocated by allocate_locked_pages + * @param pages a list of pages returned by allocate_locked_pages + */ void free_locked_pages(const std::vector& pages); /** -* Set the MMU to prohibit access to this page -*/ + * Set the MMU to prohibit access to this page + */ void page_prohibit_access(void* page); /** -* Set the MMU to allow R/W access to this page -*/ + * Set the MMU to allow R/W access to this page + */ void page_allow_access(void* page); +/** + * Run a probe instruction to test for support for a CPU instruction. + * Runs in system-specific env that catches illegal instructions; this + * function always fails if the OS doesn't provide this. + * Returns value of probe_fn, if it could run. + * If error occurs, returns negative number. + * This allows probe_fn to indicate errors of its own, if it wants. + * For example the instruction might not only be only available on some + * CPUs, but also buggy on some subset of these - the probe function + * can test to make sure the instruction works properly before + * indicating that the instruction is available. + * + * @warning on Unix systems uses signal handling in a way that is not + * thread safe. It should only be called in a single-threaded context + * (ie, at static init time). + * + * If probe_fn throws an exception the result is undefined. + * + * Return codes: + * -1 illegal instruction detected + */ +int BOTAN_TEST_API run_cpu_instruction_probe(std::function probe_fn); /** -* Run a probe instruction to test for support for a CPU instruction. -* Runs in system-specific env that catches illegal instructions; this -* function always fails if the OS doesn't provide this. -* Returns value of probe_fn, if it could run. -* If error occurs, returns negative number. -* This allows probe_fn to indicate errors of its own, if it wants. -* For example the instruction might not only be only available on some -* CPUs, but also buggy on some subset of these - the probe function -* can test to make sure the instruction works properly before -* indicating that the instruction is available. -* -* @warning on Unix systems uses signal handling in a way that is not -* thread safe. It should only be called in a single-threaded context -* (ie, at static init time). -* -* If probe_fn throws an exception the result is undefined. -* -* Return codes: -* -1 illegal instruction detected -*/ -int BOTAN_TEST_API run_cpu_instruction_probe(std::function probe_fn); - -/** -* Represents a terminal state -*/ -class BOTAN_UNSTABLE_API Echo_Suppression - { + * Represents a terminal state + */ +class BOTAN_UNSTABLE_API Echo_Suppression { public: - /** - * Reenable echo on this terminal. Can be safely called - * multiple times. May throw if an error occurs. - */ - virtual void reenable_echo() = 0; + /** + * Reenable echo on this terminal. Can be safely called + * multiple times. May throw if an error occurs. + */ + virtual void reenable_echo() = 0; - /** - * Implicitly calls reenable_echo, but swallows/ignored all - * errors which would leave the terminal in an invalid state. - */ - virtual ~Echo_Suppression() = default; - }; + /** + * Implicitly calls reenable_echo, but swallows/ignored all + * errors which would leave the terminal in an invalid state. + */ + virtual ~Echo_Suppression() = default; +}; /** -* Suppress echo on the terminal -* Returns null if this operation is not supported on the current system. -*/ + * Suppress echo on the terminal + * Returns null if this operation is not supported on the current system. + */ std::unique_ptr BOTAN_UNSTABLE_API suppress_echo_on_terminal(); -} +} // namespace OS -} +} // namespace Botan namespace Botan { /** -* Container of output buffers for Pipe -*/ -class Output_Buffers final - { + * Container of output buffers for Pipe + */ +class Output_Buffers final { public: - size_t read(uint8_t[], size_t, Pipe::message_id); - size_t peek(uint8_t[], size_t, size_t, Pipe::message_id) const; - size_t get_bytes_read(Pipe::message_id) const; - size_t remaining(Pipe::message_id) const; + size_t read(uint8_t[], size_t, Pipe::message_id); + size_t peek(uint8_t[], size_t, size_t, Pipe::message_id) const; + size_t get_bytes_read(Pipe::message_id) const; + size_t remaining(Pipe::message_id) const; - void add(class SecureQueue*); - void retire(); + void add(class SecureQueue*); + void retire(); - Pipe::message_id message_count() const; + Pipe::message_id message_count() const; + + Output_Buffers(); - Output_Buffers(); private: - class SecureQueue* get(Pipe::message_id) const; + class SecureQueue* get(Pipe::message_id) const; - std::deque> m_buffers; - Pipe::message_id m_offset; - }; + std::deque> m_buffers; + Pipe::message_id m_offset; +}; -} +} // namespace Botan namespace Botan { /** -* Returns the allowed padding schemes when using the given -* algorithm (key type) for creating digital signatures. -* -* @param algo the algorithm for which to look up supported padding schemes -* @return a vector of supported padding schemes -*/ + * Returns the allowed padding schemes when using the given + * algorithm (key type) for creating digital signatures. + * + * @param algo the algorithm for which to look up supported padding schemes + * @return a vector of supported padding schemes + */ BOTAN_TEST_API const std::vector get_sig_paddings(const std::string algo); /** -* Returns true iff the given padding scheme is valid for the given -* signature algorithm (key type). -* -* @param algo the signature algorithm to be used -* @param padding the padding scheme to be used -*/ + * Returns true iff the given padding scheme is valid for the given + * signature algorithm (key type). + * + * @param algo the signature algorithm to be used + * @param padding the padding scheme to be used + */ bool sig_algo_and_pad_ok(const std::string algo, const std::string padding); -} +} // namespace Botan namespace Botan { namespace PK_Ops { -class Encryption_with_EME : public Encryption - { +class Encryption_with_EME : public Encryption { public: - size_t max_input_bits() const override; + size_t max_input_bits() const override; - secure_vector encrypt(const uint8_t msg[], size_t msg_len, - RandomNumberGenerator& rng) override; + secure_vector encrypt(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) override; - ~Encryption_with_EME() = default; - protected: - explicit Encryption_with_EME(const std::string& eme); - private: - virtual size_t max_raw_input_bits() const = 0; - - virtual secure_vector raw_encrypt(const uint8_t msg[], size_t len, - RandomNumberGenerator& rng) = 0; - std::unique_ptr m_eme; - }; - -class Decryption_with_EME : public Decryption - { - public: - secure_vector decrypt(uint8_t& valid_mask, - const uint8_t msg[], size_t msg_len) override; - - ~Decryption_with_EME() = default; - protected: - explicit Decryption_with_EME(const std::string& eme); - private: - virtual secure_vector raw_decrypt(const uint8_t msg[], size_t len) = 0; - std::unique_ptr m_eme; - }; - -class Verification_with_EMSA : public Verification - { - public: - ~Verification_with_EMSA() = default; - - void update(const uint8_t msg[], size_t msg_len) override; - bool is_valid_signature(const uint8_t sig[], size_t sig_len) override; - - bool do_check(const secure_vector& msg, - const uint8_t sig[], size_t sig_len); - - std::string hash_for_signature() { return m_hash; } + ~Encryption_with_EME() = default; protected: - explicit Verification_with_EMSA(const std::string& emsa); - - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message in bits - */ - virtual size_t max_input_bits() const = 0; - - /** - * @return boolean specifying if this signature scheme uses - * a message prefix returned by message_prefix() - */ - virtual bool has_prefix() { return false; } - - /** - * @return the message prefix if this signature scheme uses - * a message prefix, signaled via has_prefix() - */ - virtual secure_vector message_prefix() const { throw Invalid_State("No prefix"); } - - /** - * @return boolean specifying if this key type supports message - * recovery and thus if you need to call verify() or verify_mr() - */ - virtual bool with_recovery() const = 0; - - /* - * Perform a signature check operation - * @param msg the message - * @param msg_len the length of msg in bytes - * @param sig the signature - * @param sig_len the length of sig in bytes - * @returns if signature is a valid one for message - */ - virtual bool verify(const uint8_t[], size_t, - const uint8_t[], size_t) - { - throw Invalid_State("Message recovery required"); - } - - /* - * Perform a signature operation (with message recovery) - * Only call this if with_recovery() returns true - * @param msg the message - * @param msg_len the length of msg in bytes - * @returns recovered message - */ - virtual secure_vector verify_mr(const uint8_t[], size_t) - { - throw Invalid_State("Message recovery not supported"); - } - - std::unique_ptr clone_emsa() const { return std::unique_ptr(m_emsa->clone()); } + explicit Encryption_with_EME(const std::string& eme); private: - std::unique_ptr m_emsa; - const std::string m_hash; - bool m_prefix_used; - }; + virtual size_t max_raw_input_bits() const = 0; -class Signature_with_EMSA : public Signature - { + virtual secure_vector raw_encrypt(const uint8_t msg[], size_t len, + RandomNumberGenerator& rng) = 0; + std::unique_ptr m_eme; +}; + +class Decryption_with_EME : public Decryption { public: - void update(const uint8_t msg[], size_t msg_len) override; + secure_vector decrypt(uint8_t& valid_mask, const uint8_t msg[], + size_t msg_len) override; - secure_vector sign(RandomNumberGenerator& rng) override; - protected: - explicit Signature_with_EMSA(const std::string& emsa); - ~Signature_with_EMSA() = default; - - std::string hash_for_signature() { return m_hash; } - - /** - * @return boolean specifying if this signature scheme uses - * a message prefix returned by message_prefix() - */ - virtual bool has_prefix() { return false; } - - /** - * @return the message prefix if this signature scheme uses - * a message prefix, signaled via has_prefix() - */ - virtual secure_vector message_prefix() const { throw Invalid_State("No prefix"); } - - std::unique_ptr clone_emsa() const { return std::unique_ptr(m_emsa->clone()); } - - private: - - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message in bits - */ - virtual size_t max_input_bits() const = 0; - - bool self_test_signature(const std::vector& msg, - const std::vector& sig) const; - - virtual secure_vector raw_sign(const uint8_t msg[], size_t msg_len, - RandomNumberGenerator& rng) = 0; - - std::unique_ptr m_emsa; - const std::string m_hash; - bool m_prefix_used; - }; - -class Key_Agreement_with_KDF : public Key_Agreement - { - public: - secure_vector agree(size_t key_len, - const uint8_t other_key[], size_t other_key_len, - const uint8_t salt[], size_t salt_len) override; + ~Decryption_with_EME() = default; protected: - explicit Key_Agreement_with_KDF(const std::string& kdf); - ~Key_Agreement_with_KDF() = default; - private: - virtual secure_vector raw_agree(const uint8_t w[], size_t w_len) = 0; - std::unique_ptr m_kdf; - }; + explicit Decryption_with_EME(const std::string& eme); -class KEM_Encryption_with_KDF : public KEM_Encryption - { + private: + virtual secure_vector raw_decrypt(const uint8_t msg[], size_t len) = 0; + std::unique_ptr m_eme; +}; + +class Verification_with_EMSA : public Verification { public: - void kem_encrypt(secure_vector& out_encapsulated_key, - secure_vector& out_shared_key, - size_t desired_shared_key_len, - Botan::RandomNumberGenerator& rng, - const uint8_t salt[], - size_t salt_len) override; + ~Verification_with_EMSA() = default; + + void update(const uint8_t msg[], size_t msg_len) override; + bool is_valid_signature(const uint8_t sig[], size_t sig_len) override; + + bool do_check(const secure_vector& msg, const uint8_t sig[], size_t sig_len); + + std::string hash_for_signature() { return m_hash; } protected: - virtual void raw_kem_encrypt(secure_vector& out_encapsulated_key, - secure_vector& raw_shared_key, - Botan::RandomNumberGenerator& rng) = 0; + explicit Verification_with_EMSA(const std::string& emsa); + + /** + * Get the maximum message size in bits supported by this public key. + * @return maximum message in bits + */ + virtual size_t max_input_bits() const = 0; + + /** + * @return boolean specifying if this signature scheme uses + * a message prefix returned by message_prefix() + */ + virtual bool has_prefix() { return false; } + + /** + * @return the message prefix if this signature scheme uses + * a message prefix, signaled via has_prefix() + */ + virtual secure_vector message_prefix() const { throw Invalid_State("No prefix"); } + + /** + * @return boolean specifying if this key type supports message + * recovery and thus if you need to call verify() or verify_mr() + */ + virtual bool with_recovery() const = 0; + + /* + * Perform a signature check operation + * @param msg the message + * @param msg_len the length of msg in bytes + * @param sig the signature + * @param sig_len the length of sig in bytes + * @returns if signature is a valid one for message + */ + virtual bool verify(const uint8_t[], size_t, const uint8_t[], size_t) { + throw Invalid_State("Message recovery required"); + } + + /* + * Perform a signature operation (with message recovery) + * Only call this if with_recovery() returns true + * @param msg the message + * @param msg_len the length of msg in bytes + * @returns recovered message + */ + virtual secure_vector verify_mr(const uint8_t[], size_t) { + throw Invalid_State("Message recovery not supported"); + } + + std::unique_ptr clone_emsa() const { return std::unique_ptr(m_emsa->clone()); } - explicit KEM_Encryption_with_KDF(const std::string& kdf); - ~KEM_Encryption_with_KDF() = default; private: - std::unique_ptr m_kdf; - }; + std::unique_ptr m_emsa; + const std::string m_hash; + bool m_prefix_used; +}; -class KEM_Decryption_with_KDF : public KEM_Decryption - { +class Signature_with_EMSA : public Signature { public: - secure_vector kem_decrypt(const uint8_t encap_key[], - size_t len, - size_t desired_shared_key_len, - const uint8_t salt[], - size_t salt_len) override; + void update(const uint8_t msg[], size_t msg_len) override; + + secure_vector sign(RandomNumberGenerator& rng) override; protected: - virtual secure_vector - raw_kem_decrypt(const uint8_t encap_key[], size_t len) = 0; + explicit Signature_with_EMSA(const std::string& emsa); + ~Signature_with_EMSA() = default; + + std::string hash_for_signature() { return m_hash; } + + /** + * @return boolean specifying if this signature scheme uses + * a message prefix returned by message_prefix() + */ + virtual bool has_prefix() { return false; } + + /** + * @return the message prefix if this signature scheme uses + * a message prefix, signaled via has_prefix() + */ + virtual secure_vector message_prefix() const { throw Invalid_State("No prefix"); } + + std::unique_ptr clone_emsa() const { return std::unique_ptr(m_emsa->clone()); } - explicit KEM_Decryption_with_KDF(const std::string& kdf); - ~KEM_Decryption_with_KDF() = default; private: - std::unique_ptr m_kdf; - }; + /** + * Get the maximum message size in bits supported by this public key. + * @return maximum message in bits + */ + virtual size_t max_input_bits() const = 0; -} + bool self_test_signature(const std::vector& msg, + const std::vector& sig) const; -} + virtual secure_vector raw_sign(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) = 0; + + std::unique_ptr m_emsa; + const std::string m_hash; + bool m_prefix_used; +}; + +class Key_Agreement_with_KDF : public Key_Agreement { + public: + secure_vector agree(size_t key_len, const uint8_t other_key[], size_t other_key_len, + const uint8_t salt[], size_t salt_len) override; + + protected: + explicit Key_Agreement_with_KDF(const std::string& kdf); + ~Key_Agreement_with_KDF() = default; + + private: + virtual secure_vector raw_agree(const uint8_t w[], size_t w_len) = 0; + std::unique_ptr m_kdf; +}; + +class KEM_Encryption_with_KDF : public KEM_Encryption { + public: + void kem_encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, const uint8_t salt[], + size_t salt_len) override; + + protected: + virtual void raw_kem_encrypt(secure_vector& out_encapsulated_key, + secure_vector& raw_shared_key, + Botan::RandomNumberGenerator& rng) = 0; + + explicit KEM_Encryption_with_KDF(const std::string& kdf); + ~KEM_Encryption_with_KDF() = default; + + private: + std::unique_ptr m_kdf; +}; + +class KEM_Decryption_with_KDF : public KEM_Decryption { + public: + secure_vector kem_decrypt(const uint8_t encap_key[], size_t len, + size_t desired_shared_key_len, const uint8_t salt[], + size_t salt_len) override; + + protected: + virtual secure_vector raw_kem_decrypt(const uint8_t encap_key[], size_t len) = 0; + + explicit KEM_Decryption_with_KDF(const std::string& kdf); + ~KEM_Decryption_with_KDF() = default; + + private: + std::unique_ptr m_kdf; +}; + +} // namespace PK_Ops + +} // namespace Botan namespace Botan { /** -* Polynomial doubling in GF(2^n) -*/ + * Polynomial doubling in GF(2^n) + */ void BOTAN_TEST_API poly_double_n(uint8_t out[], const uint8_t in[], size_t n); /** -* Returns true iff poly_double_n is implemented for this size. -*/ -inline bool poly_double_supported_size(size_t n) - { - return (n == 8 || n == 16 || n == 24 || n == 32 || n == 64 || n == 128); - } + * Returns true iff poly_double_n is implemented for this size. + */ +inline bool poly_double_supported_size(size_t n) { + return (n == 8 || n == 16 || n == 24 || n == 32 || n == 64 || n == 128); +} -inline void poly_double_n(uint8_t buf[], size_t n) - { - return poly_double_n(buf, buf, n); - } +inline void poly_double_n(uint8_t buf[], size_t n) { return poly_double_n(buf, buf, n); } /* -* Little endian convention - used for XTS -*/ + * Little endian convention - used for XTS + */ void BOTAN_TEST_API poly_double_n_le(uint8_t out[], const uint8_t in[], size_t n); -} +} // namespace Botan namespace Botan { -template -inline void prefetch_readonly(const T* addr, size_t length) - { +template +inline void prefetch_readonly(const T* addr, size_t length) { #if defined(__GNUG__) - const size_t Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); + const size_t Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); - for(size_t i = 0; i <= length; i += Ts_per_cache_line) - __builtin_prefetch(addr + i, 0); + for (size_t i = 0; i <= length; i += Ts_per_cache_line) __builtin_prefetch(addr + i, 0); #endif - } - -template -inline void prefetch_readwrite(const T* addr, size_t length) - { -#if defined(__GNUG__) - const size_t Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); - - for(size_t i = 0; i <= length; i += Ts_per_cache_line) - __builtin_prefetch(addr + i, 1); -#endif - } - } +template +inline void prefetch_readwrite(const T* addr, size_t length) { +#if defined(__GNUG__) + const size_t Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); + + for (size_t i = 0; i <= length; i += Ts_per_cache_line) __builtin_prefetch(addr + i, 1); +#endif +} + +} // namespace Botan + namespace Botan { class BigInt; @@ -3239,416 +2908,325 @@ class Montgomery_Params; class RandomNumberGenerator; /** -* Perform Lucas primality test -* @see FIPS 186-4 C.3.3 -* -* @warning it is possible to construct composite integers which pass -* this test alone. -* -* @param n the positive integer to test -* @param mod_n a pre-created Modular_Reducer for n -* @return true if n seems probably prime, false if n is composite -*/ + * Perform Lucas primality test + * @see FIPS 186-4 C.3.3 + * + * @warning it is possible to construct composite integers which pass + * this test alone. + * + * @param n the positive integer to test + * @param mod_n a pre-created Modular_Reducer for n + * @return true if n seems probably prime, false if n is composite + */ bool BOTAN_TEST_API is_lucas_probable_prime(const BigInt& n, const Modular_Reducer& mod_n); /** -* Perform Bailie-PSW primality test -* -* This is a combination of Miller-Rabin with base 2 and a Lucas test. No known -* composite integer passes both tests, though it is conjectured that infinitely -* many composite counterexamples exist. -* -* @param n the positive integer to test -* @param mod_n a pre-created Modular_Reducer for n -* @return true if n seems probably prime, false if n is composite -*/ + * Perform Bailie-PSW primality test + * + * This is a combination of Miller-Rabin with base 2 and a Lucas test. No known + * composite integer passes both tests, though it is conjectured that infinitely + * many composite counterexamples exist. + * + * @param n the positive integer to test + * @param mod_n a pre-created Modular_Reducer for n + * @return true if n seems probably prime, false if n is composite + */ bool BOTAN_TEST_API is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n); /** -* Perform Bailie-PSW primality test -* -* This is a combination of Miller-Rabin with base 2 and a Lucas test. No known -* composite integer passes both tests, though it is conjectured that infinitely -* many composite counterexamples exist. -* -* @param n the positive integer to test -* @return true if n seems probably prime, false if n is composite -*/ + * Perform Bailie-PSW primality test + * + * This is a combination of Miller-Rabin with base 2 and a Lucas test. No known + * composite integer passes both tests, though it is conjectured that infinitely + * many composite counterexamples exist. + * + * @param n the positive integer to test + * @return true if n seems probably prime, false if n is composite + */ bool is_bailie_psw_probable_prime(const BigInt& n); /** -* Return required number of Miller-Rabin tests in order to -* reach the specified probability of error. -* -* @param n_bits the bit-length of the integer being tested -* @param prob chance of false positive is bounded by 1/2**prob -* @param random is set if (and only if) the integer was randomly generated by us -* and thus cannot have been maliciously constructed. -*/ + * Return required number of Miller-Rabin tests in order to + * reach the specified probability of error. + * + * @param n_bits the bit-length of the integer being tested + * @param prob chance of false positive is bounded by 1/2**prob + * @param random is set if (and only if) the integer was randomly generated by us + * and thus cannot have been maliciously constructed. + */ size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random); /** -* Perform a single Miller-Rabin test with specified base -* -* @param n the positive integer to test -* @param mod_n a pre-created Modular_Reducer for n -* @param monty_n Montgomery parameters for n -* @param a the base to check -* @return result of primality test -*/ -bool passes_miller_rabin_test(const BigInt& n, - const Modular_Reducer& mod_n, - const std::shared_ptr& monty_n, - const BigInt& a); + * Perform a single Miller-Rabin test with specified base + * + * @param n the positive integer to test + * @param mod_n a pre-created Modular_Reducer for n + * @param monty_n Montgomery parameters for n + * @param a the base to check + * @return result of primality test + */ +bool passes_miller_rabin_test(const BigInt& n, const Modular_Reducer& mod_n, + const std::shared_ptr& monty_n, const BigInt& a); /** -* Perform t iterations of a Miller-Rabin primality test with random bases -* -* @param n the positive integer to test -* @param mod_n a pre-created Modular_Reducer for n -* @param rng a random number generator -* @param t number of tests to perform -* -* @return result of primality test -*/ -bool BOTAN_TEST_API is_miller_rabin_probable_prime(const BigInt& n, - const Modular_Reducer& mod_n, - RandomNumberGenerator& rng, - size_t t); + * Perform t iterations of a Miller-Rabin primality test with random bases + * + * @param n the positive integer to test + * @param mod_n a pre-created Modular_Reducer for n + * @param rng a random number generator + * @param t number of tests to perform + * + * @return result of primality test + */ +bool BOTAN_TEST_API is_miller_rabin_probable_prime(const BigInt& n, const Modular_Reducer& mod_n, + RandomNumberGenerator& rng, size_t t); -} +} // namespace Botan namespace Botan { /** -* Round up -* @param n a non-negative integer -* @param align_to the alignment boundary -* @return n rounded up to a multiple of align_to -*/ -inline size_t round_up(size_t n, size_t align_to) - { - BOTAN_ARG_CHECK(align_to != 0, "align_to must not be 0"); - - if(n % align_to) - n += align_to - (n % align_to); - return n; - } - -/** -* Round down -* @param n an integer -* @param align_to the alignment boundary -* @return n rounded down to a multiple of align_to -*/ -template -inline constexpr T round_down(T n, T align_to) - { - return (align_to == 0) ? n : (n - (n % align_to)); - } - -/** -* Clamp -*/ -inline size_t clamp(size_t n, size_t lower_bound, size_t upper_bound) - { - if(n < lower_bound) - return lower_bound; - if(n > upper_bound) - return upper_bound; - return n; - } + * Round up + * @param n a non-negative integer + * @param align_to the alignment boundary + * @return n rounded up to a multiple of align_to + */ +inline size_t round_up(size_t n, size_t align_to) { + BOTAN_ARG_CHECK(align_to != 0, "align_to must not be 0"); + if (n % align_to) n += align_to - (n % align_to); + return n; } +/** + * Round down + * @param n an integer + * @param align_to the alignment boundary + * @return n rounded down to a multiple of align_to + */ +template +inline constexpr T round_down(T n, T align_to) { + return (align_to == 0) ? n : (n - (n % align_to)); +} + +/** + * Clamp + */ +inline size_t clamp(size_t n, size_t lower_bound, size_t upper_bound) { + if (n < lower_bound) return lower_bound; + if (n > upper_bound) return upper_bound; + return n; +} + +} // namespace Botan + namespace Botan { -class BOTAN_PUBLIC_API(2,0) Integer_Overflow_Detected final : public Exception - { +class BOTAN_PUBLIC_API(2, 0) Integer_Overflow_Detected final : public Exception { public: - Integer_Overflow_Detected(const std::string& file, int line) : - Exception("Integer overflow detected at " + file + ":" + std::to_string(line)) - {} + Integer_Overflow_Detected(const std::string& file, int line) + : Exception("Integer overflow detected at " + file + ":" + std::to_string(line)) {} - ErrorType error_type() const noexcept override { return ErrorType::InternalError; } - }; - -inline size_t checked_add(size_t x, size_t y, const char* file, int line) - { - // TODO: use __builtin_x_overflow on GCC and Clang - size_t z = x + y; - if(z < x) - { - throw Integer_Overflow_Detected(file, line); - } - return z; - } - -#define BOTAN_CHECKED_ADD(x,y) checked_add(x,y,__FILE__,__LINE__) + ErrorType error_type() const noexcept override { return ErrorType::InternalError; } +}; +inline size_t checked_add(size_t x, size_t y, const char* file, int line) { + // TODO: use __builtin_x_overflow on GCC and Clang + size_t z = x + y; + if (z < x) { + throw Integer_Overflow_Detected(file, line); + } + return z; } +#define BOTAN_CHECKED_ADD(x, y) checked_add(x, y, __FILE__, __LINE__) + +} // namespace Botan + namespace Botan { -inline std::vector to_byte_vector(const std::string& s) - { - return std::vector(s.cbegin(), s.cend()); - } +inline std::vector to_byte_vector(const std::string& s) { + return std::vector(s.cbegin(), s.cend()); +} -inline std::string to_string(const secure_vector &bytes) - { - return std::string(bytes.cbegin(), bytes.cend()); - } +inline std::string to_string(const secure_vector& bytes) { + return std::string(bytes.cbegin(), bytes.cend()); +} /** -* Return the keys of a map as a std::set -*/ -template -std::set map_keys_as_set(const std::map& kv) - { - std::set s; - for(auto&& i : kv) - { - s.insert(i.first); - } - return s; - } + * Return the keys of a map as a std::set + */ +template +std::set map_keys_as_set(const std::map& kv) { + std::set s; + for (auto&& i : kv) { + s.insert(i.first); + } + return s; +} /* -* Searching through a std::map -* @param mapping the map to search -* @param key is what to look for -* @param null_result is the value to return if key is not in mapping -* @return mapping[key] or null_result -*/ -template -inline V search_map(const std::map& mapping, - const K& key, - const V& null_result = V()) - { - auto i = mapping.find(key); - if(i == mapping.end()) - return null_result; - return i->second; - } + * Searching through a std::map + * @param mapping the map to search + * @param key is what to look for + * @param null_result is the value to return if key is not in mapping + * @return mapping[key] or null_result + */ +template +inline V search_map(const std::map& mapping, const K& key, const V& null_result = V()) { + auto i = mapping.find(key); + if (i == mapping.end()) return null_result; + return i->second; +} -template -inline R search_map(const std::map& mapping, const K& key, - const R& null_result, const R& found_result) - { - auto i = mapping.find(key); - if(i == mapping.end()) - return null_result; - return found_result; - } +template +inline R search_map(const std::map& mapping, const K& key, const R& null_result, + const R& found_result) { + auto i = mapping.find(key); + if (i == mapping.end()) return null_result; + return found_result; +} /* -* Insert a key/value pair into a multimap -*/ -template -void multimap_insert(std::multimap& multimap, - const K& key, const V& value) - { - multimap.insert(std::make_pair(key, value)); - } + * Insert a key/value pair into a multimap + */ +template +void multimap_insert(std::multimap& multimap, const K& key, const V& value) { + multimap.insert(std::make_pair(key, value)); +} /** -* Existence check for values -*/ -template -bool value_exists(const std::vector& vec, - const T& val) - { - for(size_t i = 0; i != vec.size(); ++i) - if(vec[i] == val) - return true; - return false; - } - -template -void map_remove_if(Pred pred, T& assoc) - { - auto i = assoc.begin(); - while(i != assoc.end()) - { - if(pred(i->first)) - assoc.erase(i++); - else - i++; - } - } - + * Existence check for values + */ +template +bool value_exists(const std::vector& vec, const T& val) { + for (size_t i = 0; i != vec.size(); ++i) + if (vec[i] == val) return true; + return false; } +template +void map_remove_if(Pred pred, T& assoc) { + auto i = assoc.begin(); + while (i != assoc.end()) { + if (pred(i->first)) + assoc.erase(i++); + else + i++; + } +} + +} // namespace Botan + namespace Botan { -class BOTAN_TEST_API Timer final - { +class BOTAN_TEST_API Timer final { public: - Timer(const std::string& name, - const std::string& provider, - const std::string& doing, - uint64_t event_mult, - size_t buf_size, - double clock_cycle_ratio, - uint64_t clock_speed) - : m_name(name + ((provider.empty() || provider == "base") ? "" : " [" + provider + "]")) - , m_doing(doing) - , m_buf_size(buf_size) - , m_event_mult(event_mult) - , m_clock_cycle_ratio(clock_cycle_ratio) - , m_clock_speed(clock_speed) - {} + Timer(const std::string& name, const std::string& provider, const std::string& doing, + uint64_t event_mult, size_t buf_size, double clock_cycle_ratio, uint64_t clock_speed) + : m_name(name + ((provider.empty() || provider == "base") ? "" : " [" + provider + "]")), + m_doing(doing), + m_buf_size(buf_size), + m_event_mult(event_mult), + m_clock_cycle_ratio(clock_cycle_ratio), + m_clock_speed(clock_speed) {} - Timer(const std::string& name) : - Timer(name, "", "", 1, 0, 0.0, 0) - {} + Timer(const std::string& name) : Timer(name, "", "", 1, 0, 0.0, 0) {} - Timer(const std::string& name, size_t buf_size) : - Timer(name, "", "", buf_size, buf_size, 0.0, 0) - {} + Timer(const std::string& name, size_t buf_size) + : Timer(name, "", "", buf_size, buf_size, 0.0, 0) {} - Timer(const Timer& other) = default; - Timer& operator=(const Timer& other) = default; + Timer(const Timer& other) = default; + Timer& operator=(const Timer& other) = default; - void start(); + void start(); - void stop(); + void stop(); - bool under(std::chrono::milliseconds msec) - { - return (milliseconds() < msec.count()); - } + bool under(std::chrono::milliseconds msec) { return (milliseconds() < msec.count()); } - class Timer_Scope final - { - public: - explicit Timer_Scope(Timer& timer) - : m_timer(timer) - { - m_timer.start(); - } - ~Timer_Scope() - { - try - { - m_timer.stop(); - } - catch(...) {} - } - private: - Timer& m_timer; - }; + class Timer_Scope final { + public: + explicit Timer_Scope(Timer& timer) : m_timer(timer) { m_timer.start(); } + ~Timer_Scope() { + try { + m_timer.stop(); + } catch (...) { + } + } - template - auto run(F f) -> decltype(f()) - { - Timer_Scope timer(*this); - return f(); - } + private: + Timer& m_timer; + }; - template - void run_until_elapsed(std::chrono::milliseconds msec, F f) - { - while(this->under(msec)) - { + template + auto run(F f) -> decltype(f()) { + Timer_Scope timer(*this); + return f(); + } + + template + void run_until_elapsed(std::chrono::milliseconds msec, F f) { + while (this->under(msec)) { run(f); - } - } + } + } - uint64_t value() const - { - return m_time_used; - } + uint64_t value() const { return m_time_used; } - double seconds() const - { - return milliseconds() / 1000.0; - } + double seconds() const { return milliseconds() / 1000.0; } - double milliseconds() const - { - return value() / 1000000.0; - } + double milliseconds() const { return value() / 1000000.0; } - double ms_per_event() const - { - return milliseconds() / events(); - } + double ms_per_event() const { return milliseconds() / events(); } - uint64_t cycles_consumed() const - { - if(m_clock_speed != 0) - { + uint64_t cycles_consumed() const { + if (m_clock_speed != 0) { return static_cast((m_clock_speed * value()) / 1000.0); - } - return m_cpu_cycles_used; - } + } + return m_cpu_cycles_used; + } - uint64_t events() const - { - return m_event_count * m_event_mult; - } + uint64_t events() const { return m_event_count * m_event_mult; } - const std::string& get_name() const - { - return m_name; - } + const std::string& get_name() const { return m_name; } - const std::string& doing() const - { - return m_doing; - } + const std::string& doing() const { return m_doing; } - size_t buf_size() const - { - return m_buf_size; - } + size_t buf_size() const { return m_buf_size; } - double bytes_per_second() const - { - return seconds() > 0.0 ? events() / seconds() : 0.0; - } + double bytes_per_second() const { return seconds() > 0.0 ? events() / seconds() : 0.0; } - double events_per_second() const - { - return seconds() > 0.0 ? events() / seconds() : 0.0; - } + double events_per_second() const { return seconds() > 0.0 ? events() / seconds() : 0.0; } - double seconds_per_event() const - { - return events() > 0 ? seconds() / events() : 0.0; - } + double seconds_per_event() const { return events() > 0 ? seconds() / events() : 0.0; } - void set_custom_msg(const std::string& s) - { - m_custom_msg = s; - } + void set_custom_msg(const std::string& s) { m_custom_msg = s; } - bool operator<(const Timer& other) const; + bool operator<(const Timer& other) const; - std::string to_string() const; + std::string to_string() const; private: - std::string result_string_bps() const; - std::string result_string_ops() const; + std::string result_string_bps() const; + std::string result_string_ops() const; - // const data - std::string m_name, m_doing; - size_t m_buf_size; - uint64_t m_event_mult; - double m_clock_cycle_ratio; - uint64_t m_clock_speed; + // const data + std::string m_name, m_doing; + size_t m_buf_size; + uint64_t m_event_mult; + double m_clock_cycle_ratio; + uint64_t m_clock_speed; - // set at runtime - std::string m_custom_msg; - uint64_t m_time_used = 0, m_timer_start = 0; - uint64_t m_event_count = 0; + // set at runtime + std::string m_custom_msg; + uint64_t m_time_used = 0, m_timer_start = 0; + uint64_t m_event_count = 0; - uint64_t m_max_time = 0, m_min_time = 0; - uint64_t m_cpu_cycles_start = 0, m_cpu_cycles_used = 0; - }; + uint64_t m_max_time = 0, m_min_time = 0; + uint64_t m_cpu_cycles_start = 0, m_cpu_cycles_used = 0; +}; -} +} // namespace Botan -#endif // BOTAN_AMALGAMATION_INTERNAL_H_ +#endif // BOTAN_AMALGAMATION_INTERNAL_H_ diff --git a/src/libraries/botan/botanwrapper.cpp b/src/libraries/botan/botanwrapper.cpp index a9f615160..1abbaf864 100644 --- a/src/libraries/botan/botanwrapper.cpp +++ b/src/libraries/botan/botanwrapper.cpp @@ -3,16 +3,16 @@ #include #ifdef USE_SYSTEM_BOTAN -#include -#include #include +#include #include -#include -#include #include +#include +#include +#include +#include #include #include -#include #else #include "botan.h" #endif @@ -54,16 +54,15 @@ QString BotanWrapper::Encrypt(const QString &Data) { mSalt.data(); // Create the master key - Botan::SecureVector mMaster = pbkdf2.derive_key( - 48, - mPassword.toStdString(), - &mSalt[0], mSalt.size(), - PBKDF2_ITERATIONS).bits_of(); + Botan::SecureVector mMaster = + pbkdf2 + .derive_key(48, mPassword.toStdString(), &mSalt[0], mSalt.size(), PBKDF2_ITERATIONS) + .bits_of(); Botan::SymmetricKey mKey = kdf->derive_key(32, mMaster, "salt1"); Botan::InitializationVector mIV = kdf->derive_key(16, mMaster, "salt2"); Botan::Pipe pipe(get_cipher("AES-256/CBC/PKCS7", mKey, mIV, Botan::ENCRYPTION), - new Botan::Base64_Encoder); + new Botan::Base64_Encoder); pipe.process_msg(Data.toStdString()); QString Value = QString::fromStdString(pipe.read_all_as_string(0)); return Value; @@ -75,29 +74,27 @@ QString BotanWrapper::Encrypt(const QString &Data) { QString BotanWrapper::Decrypt(const QString &Data) { try { - //Setup the key derive functions + // Setup the key derive functions Botan::PKCS5_PBKDF2 pbkdf2(new Botan::HMAC(new Botan::SHA_160)); const uint32_t PBKDF2_ITERATIONS = 8192; - //Create the KEY and IV + // Create the KEY and IV Botan::KDF *kdf = Botan::get_kdf("KDF2(SHA-1)"); - //Create the master key - Botan::SecureVector mMaster = pbkdf2.derive_key( - 48, - mPassword.toStdString(), - &mSalt[0], mSalt.size(), - PBKDF2_ITERATIONS).bits_of(); + // Create the master key + Botan::SecureVector mMaster = + pbkdf2 + .derive_key(48, mPassword.toStdString(), &mSalt[0], mSalt.size(), PBKDF2_ITERATIONS) + .bits_of(); Botan::SymmetricKey mKey = kdf->derive_key(32, mMaster, "salt1"); Botan::InitializationVector mIV = kdf->derive_key(16, mMaster, "salt2"); Botan::Pipe pipe(new Botan::Base64_Decoder, - get_cipher("AES-256/CBC/PKCS7", mKey, mIV, Botan::DECRYPTION)); + get_cipher("AES-256/CBC/PKCS7", mKey, mIV, Botan::DECRYPTION)); pipe.process_msg(Data.toStdString()); QString Value = QString::fromStdString(pipe.read_all_as_string(0)); return Value; - } - catch (Botan::Exception &e) { + } catch (Botan::Exception &e) { qWarning() << "[Botan Error] " << e.what(); return QString(); } @@ -111,8 +108,7 @@ void BotanWrapper::setPassword(const QString &Password) { void BotanWrapper::setSalt(const QString &Salt) { QByteArray cBytes = Salt.toLatin1(); - if (cBytes.size() > 48) - cBytes.resize(48); + if (cBytes.size() > 48) cBytes.resize(48); mSalt.fill(0); std::copy(cBytes.cbegin(), cBytes.cend(), mSalt.begin()); diff --git a/src/libraries/botan/botanwrapper.h b/src/libraries/botan/botanwrapper.h index 5c45120ea..b3d590309 100644 --- a/src/libraries/botan/botanwrapper.h +++ b/src/libraries/botan/botanwrapper.h @@ -4,44 +4,43 @@ #include #include -class BotanWrapper -{ -public: +class BotanWrapper { + public: BotanWrapper(); - + /*! - * Creates a hash - * @param Data The string to hash - */ + * Creates a hash + * @param Data The string to hash + */ QString Hash(const QString &Data); /*! - * Returns a Base64 encrypted QString - * @param Data The string to encypt - */ + * Returns a Base64 encrypted QString + * @param Data The string to encypt + */ QString Encrypt(const QString &Data); /*! - * Returns a decrypted string from a Base64 encypted string - * @param Data The string to encypt - */ + * Returns a decrypted string from a Base64 encypted string + * @param Data The string to encypt + */ QString Decrypt(const QString &Data); /*! - * Sets the Password - * @param Password The password - */ + * Sets the Password + * @param Password The password + */ void setPassword(const QString &Password); /*! - * Sets the Salt - * @param Salt The salt value - */ + * Sets the Salt + * @param Salt The salt value + */ void setSalt(const QString &Salt); -private: + private: QVector mSalt; QString mPassword; }; -#endif // BOTANWRAPPER_H +#endif // BOTANWRAPPER_H diff --git a/src/libraries/diff_match_patch/CMakeLists.txt b/src/libraries/diff_match_patch/CMakeLists.txt index 6966e6ba6..f231b3c03 100644 --- a/src/libraries/diff_match_patch/CMakeLists.txt +++ b/src/libraries/diff_match_patch/CMakeLists.txt @@ -1,19 +1,12 @@ cmake_minimum_required(VERSION 3.5) project(DiffMatchPatchLib) -add_library(diff_match_patch STATIC - diff_match_patch.h - diff_match_patch.cpp -) +add_library(diff_match_patch STATIC diff_match_patch.h diff_match_patch.cpp) add_library(Google::DiffMatchPatch ALIAS diff_match_patch) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) -target_include_directories(diff_match_patch PUBLIC - ${CMAKE_CURRENT_LIST_DIR} -) +target_include_directories(diff_match_patch PUBLIC ${CMAKE_CURRENT_LIST_DIR}) -target_link_libraries(diff_match_patch PUBLIC - Qt${QT_VERSION_MAJOR}::Core -) +target_link_libraries(diff_match_patch PUBLIC Qt${QT_VERSION_MAJOR}::Core) diff --git a/src/libraries/fakevim/CMakeLists.txt b/src/libraries/fakevim/CMakeLists.txt index b989bfdcd..af648009f 100644 --- a/src/libraries/fakevim/CMakeLists.txt +++ b/src/libraries/fakevim/CMakeLists.txt @@ -5,20 +5,13 @@ project(fakevim VERSION 0.0.1) set(bin fakevim) # Public headers -set(${bin}_public_headers - fakevim/fakevimactions.h - fakevim/fakevimhandler.h - ) +set(${bin}_public_headers fakevim/fakevimactions.h fakevim/fakevimhandler.h) # Source files common for all platforms set(${bin}_sources - fakevim/fakevimactions.cpp - fakevim/fakevimhandler.cpp - fakevim/utils/hostosinfo.cpp - fakevim/utils/osspecificaspects.h - fakevim/utils/qtcassert.cpp - ${${bin}_public_headers} - ) + fakevim/fakevimactions.cpp fakevim/fakevimhandler.cpp + fakevim/utils/hostosinfo.cpp fakevim/utils/osspecificaspects.h + fakevim/utils/qtcassert.cpp ${${bin}_public_headers}) # Required pkg-config packages set(${bin}_pkg_config_requires) @@ -30,49 +23,42 @@ include(cmake/pkg-config.cmake) # Files with Q_OBJECT macros to pass to moc utility set(CMAKE_INCLUDE_CURRENT_DIR ON) -if (QT_VERSION_MAJOR EQUAL 6) - qt6_wrap_cpp(${bin}_mocced "fakevim/fakevimhandler.h") +if(QT_VERSION_MAJOR EQUAL 6) + qt6_wrap_cpp(${bin}_mocced "fakevim/fakevimhandler.h") else() - qt5_wrap_cpp(${bin}_mocced "fakevim/fakevimhandler.h") + qt5_wrap_cpp(${bin}_mocced "fakevim/fakevimhandler.h") endif() target_sources(${bin} PRIVATE ${${bin}_mocced}) -target_compile_definitions(${bin} PRIVATE - QT_NO_CAST_TO_ASCII - QT_RESTRICTED_CAST_FROM_ASCII - QTCREATOR_UTILS_STATIC_LIB -) +target_compile_definitions( + ${bin} PRIVATE QT_NO_CAST_TO_ASCII QT_RESTRICTED_CAST_FROM_ASCII + QTCREATOR_UTILS_STATIC_LIB) option(BUILD_TESTS "Build tests") -if (BUILD_TESTS) - message(STATUS "Building tests") +if(BUILD_TESTS) + message(STATUS "Building tests") - find_package(Qt5Test REQUIRED) + find_package(Qt5Test REQUIRED) - add_executable(fakevim_test - tests/fakevim_test.cpp - tests/fakevimplugin.h - example/editor.cpp - ) - set_property(TARGET fakevim_test PROPERTY AUTOMOC ON) - target_link_libraries(fakevim_test fakevim Qt5::Widgets Qt5::Test) + add_executable(fakevim_test tests/fakevim_test.cpp tests/fakevimplugin.h + example/editor.cpp) + set_property(TARGET fakevim_test PROPERTY AUTOMOC ON) + target_link_libraries(fakevim_test fakevim Qt5::Widgets Qt5::Test) - target_include_directories(fakevim_test PRIVATE - ${CMAKE_SOURCE_DIR}/fakevim - ${CMAKE_SOURCE_DIR} - ) + target_include_directories(fakevim_test PRIVATE ${CMAKE_SOURCE_DIR}/fakevim + ${CMAKE_SOURCE_DIR}) - add_test(fakevim_test fakevim_test) - enable_testing() + add_test(fakevim_test fakevim_test) + enable_testing() endif() option(BUILD_EXAMPLE "Build example") -if (BUILD_EXAMPLE) - message(STATUS "Building example") +if(BUILD_EXAMPLE) + message(STATUS "Building example") - add_executable(fakevim_example example/main.cpp example/editor.cpp) - set_property(TARGET fakevim_example PROPERTY AUTOMOC ON) + add_executable(fakevim_example example/main.cpp example/editor.cpp) + set_property(TARGET fakevim_example PROPERTY AUTOMOC ON) - target_link_libraries(fakevim_example fakevim) - target_link_libraries(fakevim_example Qt5::Widgets) + target_link_libraries(fakevim_example fakevim) + target_link_libraries(fakevim_example Qt5::Widgets) endif() diff --git a/src/libraries/fakevim/cmake/cxx17.cmake b/src/libraries/fakevim/cmake/cxx17.cmake index 345814d69..130d54b68 100644 --- a/src/libraries/fakevim/cmake/cxx17.cmake +++ b/src/libraries/fakevim/cmake/cxx17.cmake @@ -1,5 +1,5 @@ -if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.1) - set(CMAKE_CXX_STANDARD 17) +if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.1) + set(CMAKE_CXX_STANDARD 17) else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") endif() diff --git a/src/libraries/fakevim/cmake/library.cmake b/src/libraries/fakevim/cmake/library.cmake index 0fa9c47fb..16257130d 100644 --- a/src/libraries/fakevim/cmake/library.cmake +++ b/src/libraries/fakevim/cmake/library.cmake @@ -1,83 +1,71 @@ -set(INSTALL_LIB_DIR "lib${LIB_SUFFIX}" CACHE PATH - "Installation directory for libraries") -set(INSTALL_BIN_DIR "bin" CACHE PATH - "Installation directory for executables") -set(INSTALL_INCLUDE_DIR "include/${bin}" CACHE PATH - "Installation directory for header files") -set(INSTALL_CMAKE_DIR "lib${LIB_SUFFIX}/cmake/${bin}" CACHE PATH - "Installation directory for CMake files") +set(INSTALL_LIB_DIR + "lib${LIB_SUFFIX}" + CACHE PATH "Installation directory for libraries") +set(INSTALL_BIN_DIR + "bin" + CACHE PATH "Installation directory for executables") +set(INSTALL_INCLUDE_DIR + "include/${bin}" + CACHE PATH "Installation directory for header files") +set(INSTALL_CMAKE_DIR + "lib${LIB_SUFFIX}/cmake/${bin}" + CACHE PATH "Installation directory for CMake files") # Shared or static library option(CREATE_STATIC_LIBRARY "Create static library" OFF) -if (CREATE_STATIC_LIBRARY) - set(libtype STATIC) +if(CREATE_STATIC_LIBRARY) + set(libtype STATIC) else() - set(libtype SHARED) + set(libtype SHARED) endif() add_library(${bin} ${libtype} ${${bin}_sources}) -set_target_properties(${bin} PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} - ) +set_target_properties(${bin} PROPERTIES VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR}) # Headers set(export_header "${CMAKE_CURRENT_BINARY_DIR}/private/${bin}_export.h") -set_target_properties(${bin} PROPERTIES - PUBLIC_HEADER "${${bin}_public_headers}" - PRIVATE_HEADER "${export_header}") +set_target_properties(${bin} PROPERTIES PUBLIC_HEADER "${${bin}_public_headers}" + PRIVATE_HEADER "${export_header}") -target_include_directories(${bin} - PRIVATE $ - INTERFACE $ - ) +target_include_directories( + ${bin} + PRIVATE $ + INTERFACE $) install( - TARGETS ${bin} EXPORT ${bin}Targets - RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin - LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib - ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib - PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT dev - PRIVATE_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/private" COMPONENT dev - ) + TARGETS ${bin} + EXPORT ${bin}Targets + RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin + LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib + ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib + PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT dev + PRIVATE_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/private" COMPONENT dev) -# Generate and install CMake files for the library so `find_package()` can be used with CMake. -# For more info: https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#creating-packages +# Generate and install CMake files for the library so `find_package()` +# can be used with CMake. For more info: +# https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#creating-packages include(GenerateExportHeader) generate_export_header(${bin} EXPORT_FILE_NAME "${export_header}") include(CMakePackageConfigHelpers) write_basic_package_version_file( - "${CMAKE_CURRENT_BINARY_DIR}/${bin}ConfigVersion.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY AnyNewerVersion - ) + "${CMAKE_CURRENT_BINARY_DIR}/${bin}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion) -export( - EXPORT ${bin}Targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/${bin}Targets.cmake" - ) -configure_file( - cmake/${bin}Config.cmake - "${CMAKE_CURRENT_BINARY_DIR}/${bin}Config.cmake" - COPYONLY - ) +export(EXPORT ${bin}Targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/${bin}Targets.cmake") +configure_file(cmake/${bin}Config.cmake + "${CMAKE_CURRENT_BINARY_DIR}/${bin}Config.cmake" COPYONLY) install( - EXPORT ${bin}Targets - FILE - ${bin}Targets.cmake - DESTINATION - "${INSTALL_CMAKE_DIR}" - COMPONENT - dev - ) + EXPORT ${bin}Targets + FILE ${bin}Targets.cmake + DESTINATION "${INSTALL_CMAKE_DIR}" + COMPONENT dev) install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/${bin}Config.cmake" + FILES "${CMAKE_CURRENT_BINARY_DIR}/${bin}Config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${bin}ConfigVersion.cmake" - DESTINATION - "${INSTALL_CMAKE_DIR}" - COMPONENT - dev - ) + DESTINATION "${INSTALL_CMAKE_DIR}" + COMPONENT dev) diff --git a/src/libraries/fakevim/cmake/pkg-config.cmake b/src/libraries/fakevim/cmake/pkg-config.cmake index 719b9061c..c3aea9dc7 100644 --- a/src/libraries/fakevim/cmake/pkg-config.cmake +++ b/src/libraries/fakevim/cmake/pkg-config.cmake @@ -4,19 +4,14 @@ set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/${bin}") set(PKG_CONFIG_LIBS "-L\${libdir} -l${bin}") set(PKG_CONFIG_CFLAGS "-I\${includedir}") -#configure_file( -# "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.in" -# "${CMAKE_CURRENT_BINARY_DIR}/${bin}.pc" -# ) +# configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.in" +# "${CMAKE_CURRENT_BINARY_DIR}/${bin}.pc" ) -set(INSTALL_PKG_CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" +set(INSTALL_PKG_CONFIG_DIR + "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" CACHE PATH "Installation directory for pkg-config files") install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/${bin}.pc" - DESTINATION - "${INSTALL_PKG_CONFIG_DIR}" - COMPONENT - dev - ) + FILES "${CMAKE_CURRENT_BINARY_DIR}/${bin}.pc" + DESTINATION "${INSTALL_PKG_CONFIG_DIR}" + COMPONENT dev) diff --git a/src/libraries/fakevim/cmake/qt.cmake b/src/libraries/fakevim/cmake/qt.cmake index 9b2e3ace3..61706e4d8 100644 --- a/src/libraries/fakevim/cmake/qt.cmake +++ b/src/libraries/fakevim/cmake/qt.cmake @@ -3,4 +3,5 @@ find_package(Qt${QT_VERSION_MAJOR}Widgets REQUIRED) # include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) target_link_libraries(${bin} Qt${QT_VERSION_MAJOR}::Widgets) -set(${bin}_pkg_config_requires ${${bin}_pkg_config_requires} Qt${QT_VERSION_MAJOR}::Widgets) +set(${bin}_pkg_config_requires ${${bin}_pkg_config_requires} + Qt${QT_VERSION_MAJOR}::Widgets) diff --git a/src/libraries/fakevim/fakevim/fakevimactions.cpp b/src/libraries/fakevim/fakevim/fakevimactions.cpp index 95c1c02bf..bb3898544 100644 --- a/src/libraries/fakevim/fakevim/fakevimactions.cpp +++ b/src/libraries/fakevim/fakevim/fakevimactions.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "fakevimactions.h" + #include "fakevimhandler.h" // Please do not add any direct dependencies to other Qt Creator code here. @@ -41,80 +42,62 @@ namespace FakeVim { namespace Internal { #ifdef FAKEVIM_STANDALONE -FvBaseAspect::FvBaseAspect() -{ -} +FvBaseAspect::FvBaseAspect() {} -void FvBaseAspect::setValue(const QVariant &value) -{ - m_value = value; -} +void FvBaseAspect::setValue(const QVariant &value) { m_value = value; } -QVariant FvBaseAspect::value() const -{ - return m_value; -} +QVariant FvBaseAspect::value() const { return m_value; } -void FvBaseAspect::setDefaultValue(const QVariant &value) -{ +void FvBaseAspect::setDefaultValue(const QVariant &value) { m_defaultValue = value; m_value = value; } -QVariant FvBaseAspect::defaultValue() const -{ - return m_defaultValue; -} +QVariant FvBaseAspect::defaultValue() const { return m_defaultValue; } -void FvBaseAspect::setSettingsKey(const QString &group, const QString &key) -{ +void FvBaseAspect::setSettingsKey(const QString &group, const QString &key) { m_settingsGroup = group; m_settingsKey = key; } -QString FvBaseAspect::settingsKey() const -{ - return m_settingsKey; -} +QString FvBaseAspect::settingsKey() const { return m_settingsKey; } #endif -FakeVimSettings::FakeVimSettings() -{ +FakeVimSettings::FakeVimSettings() { #ifndef FAKEVIM_STANDALONE - setup(&useFakeVim, false, "UseFakeVim", {}, tr("Use FakeVim")); + setup(&useFakeVim, false, "UseFakeVim", {}, tr("Use FakeVim")); #endif // Specific FakeVim settings - setup(&readVimRc, false, "ReadVimRc", {}, tr("Read .vimrc from location:")); - setup(&vimRcPath, QString(), "VimRcPath", {}, {}); // tr("Path to .vimrc") - setup(&showMarks, false, "ShowMarks", "sm", tr("Show position of text marks")); + setup(&readVimRc, false, "ReadVimRc", {}, tr("Read .vimrc from location:")); + setup(&vimRcPath, QString(), "VimRcPath", {}, {}); // tr("Path to .vimrc") + setup(&showMarks, false, "ShowMarks", "sm", tr("Show position of text marks")); setup(&passControlKey, false, "PassControlKey", "pck", tr("Pass control keys")); - setup(&passKeys, true, "PassKeys", "pk", tr("Pass keys in insert mode")); + setup(&passKeys, true, "PassKeys", "pk", tr("Pass keys in insert mode")); // Emulated Vsetting - setup(&startOfLine, true, "StartOfLine", "sol", tr("Start of line")); - setup(&tabStop, 8, "TabStop", "ts", tr("Tabulator size:")); - setup(&smartTab, false, "SmartTab", "sta", tr("Smart tabulators")); - setup(&hlSearch, true, "HlSearch", "hls", tr("Highlight search results")); - setup(&shiftWidth, 8, "ShiftWidth", "sw", tr("Shift width:")); - setup(&expandTab, false, "ExpandTab", "et", tr("Expand tabulators")); - setup(&autoIndent, false, "AutoIndent", "ai", tr("Automatic indentation")); - setup(&smartIndent, false, "SmartIndent", "si", tr("Smart tabulators")); - setup(&incSearch, true, "IncSearch", "is", tr("Incremental search")); - setup(&useCoreSearch, false, "UseCoreSearch", "ucs", tr("Use search dialog")); - setup(&smartCase, false, "SmartCase", "scs", tr("Use smartcase")); - setup(&ignoreCase, false, "IgnoreCase", "ic", tr("Use ignorecase")); - setup(&wrapScan, true, "WrapScan", "ws", tr("Use wrapscan")); - setup(&tildeOp, false, "TildeOp", "top", tr("Use tildeop")); - setup(&showCmd, true, "ShowCmd", "sc", tr("Show partial command")); - setup(&relativeNumber, false, "RelativeNumber", "rnu", tr("Show line numbers relative to cursor")); - setup(&blinkingCursor, false, "BlinkingCursor", "bc", tr("Blinking cursor")); - setup(&scrollOff, 0, "ScrollOff", "so", tr("Scroll offset:")); - setup(&backspace, "indent,eol,start", - "Backspace", "bs", tr("Backspace:")); - setup(&isKeyword, "@,48-57,_,192-255,a-z,A-Z", - "IsKeyword", "isk", tr("Keyword characters:")); - setup(&clipboard, {}, "Clipboard", "cb", tr("")); - setup(&formatOptions, {}, "formatoptions", "fo", tr("")); + setup(&startOfLine, true, "StartOfLine", "sol", tr("Start of line")); + setup(&tabStop, 8, "TabStop", "ts", tr("Tabulator size:")); + setup(&smartTab, false, "SmartTab", "sta", tr("Smart tabulators")); + setup(&hlSearch, true, "HlSearch", "hls", tr("Highlight search results")); + setup(&shiftWidth, 8, "ShiftWidth", "sw", tr("Shift width:")); + setup(&expandTab, false, "ExpandTab", "et", tr("Expand tabulators")); + setup(&autoIndent, false, "AutoIndent", "ai", tr("Automatic indentation")); + setup(&smartIndent, false, "SmartIndent", "si", tr("Smart tabulators")); + setup(&incSearch, true, "IncSearch", "is", tr("Incremental search")); + setup(&useCoreSearch, false, "UseCoreSearch", "ucs", tr("Use search dialog")); + setup(&smartCase, false, "SmartCase", "scs", tr("Use smartcase")); + setup(&ignoreCase, false, "IgnoreCase", "ic", tr("Use ignorecase")); + setup(&wrapScan, true, "WrapScan", "ws", tr("Use wrapscan")); + setup(&tildeOp, false, "TildeOp", "top", tr("Use tildeop")); + setup(&showCmd, true, "ShowCmd", "sc", tr("Show partial command")); + setup(&relativeNumber, false, "RelativeNumber", "rnu", + tr("Show line numbers relative to cursor")); + setup(&blinkingCursor, false, "BlinkingCursor", "bc", tr("Blinking cursor")); + setup(&scrollOff, 0, "ScrollOff", "so", tr("Scroll offset:")); + setup(&backspace, "indent,eol,start", "Backspace", "bs", tr("Backspace:")); + setup(&isKeyword, "@,48-57,_,192-255,a-z,A-Z", "IsKeyword", "isk", tr("Keyword characters:")); + setup(&clipboard, {}, "Clipboard", "cb", tr("")); + setup(&formatOptions, {}, "formatoptions", "fo", tr("")); // Emulated plugins setup(&emulateVimCommentary, false, "commentary", {}, "vim-commentary"); @@ -126,15 +109,18 @@ FakeVimSettings::FakeVimSettings() // Some polish useFakeVim.setDisplayName(tr("Use Vim-style Editing")); - relativeNumber.setToolTip(tr("Displays line numbers relative to the line containing " - "text cursor.")); + relativeNumber.setToolTip( + tr("Displays line numbers relative to the line containing " + "text cursor.")); - passControlKey.setToolTip(tr("Does not interpret key sequences like Ctrl-S in FakeVim " - "but handles them as regular shortcuts. This gives easier access to core functionality " - "at the price of losing some features of FakeVim.")); + passControlKey.setToolTip( + tr("Does not interpret key sequences like Ctrl-S in FakeVim " + "but handles them as regular shortcuts. This gives easier access to core functionality " + "at the price of losing some features of FakeVim.")); - passKeys.setToolTip(tr("Does not interpret some key presses in insert mode so that " - "code can be properly completed and expanded.")); + passKeys.setToolTip( + tr("Does not interpret some key presses in insert mode so that " + "code can be properly completed and expanded.")); tabStop.setToolTip(tr("Vim tabstop option.")); @@ -142,11 +128,12 @@ FakeVimSettings::FakeVimSettings() backspace.setDisplayStyle(FvStringAspect::LineEditDisplay); isKeyword.setDisplayStyle(FvStringAspect::LineEditDisplay); - const QString vimrcDefault = QLatin1String(HostOsInfo::isAnyUnixHost() - ? "$HOME/.vimrc" : "%USERPROFILE%\\_vimrc"); + const QString vimrcDefault = + QLatin1String(HostOsInfo::isAnyUnixHost() ? "$HOME/.vimrc" : "%USERPROFILE%\\_vimrc"); vimRcPath.setExpectedKind(PathChooser::File); - vimRcPath.setToolTip(tr("Keep empty to use the default path, i.e. " - "%USERPROFILE%\\_vimrc on Windows, ~/.vimrc otherwise.")); + vimRcPath.setToolTip( + tr("Keep empty to use the default path, i.e. " + "%USERPROFILE%\\_vimrc on Windows, ~/.vimrc otherwise.")); vimRcPath.setPlaceHolderText(tr("Default: %1").arg(vimrcDefault)); vimRcPath.setDisplayStyle(FvStringAspect::PathChooserDisplay); #endif @@ -154,31 +141,22 @@ FakeVimSettings::FakeVimSettings() FakeVimSettings::~FakeVimSettings() = default; -FvBaseAspect *FakeVimSettings::item(const QString &name) -{ +FvBaseAspect *FakeVimSettings::item(const QString &name) { return m_nameToAspect.value(name, nullptr); } -QString FakeVimSettings::trySetValue(const QString &name, const QString &value) -{ +QString FakeVimSettings::trySetValue(const QString &name, const QString &value) { FvBaseAspect *aspect = m_nameToAspect.value(name, nullptr); - if (!aspect) - return tr("Unknown option: %1").arg(name); + if (!aspect) return tr("Unknown option: %1").arg(name); if (aspect == &tabStop || aspect == &shiftWidth) { - if (value.toInt() <= 0) - return tr("Argument must be positive: %1=%2") - .arg(name).arg(value); + if (value.toInt() <= 0) return tr("Argument must be positive: %1=%2").arg(name).arg(value); } aspect->setValue(value); return QString(); } -void FakeVimSettings::setup(FvBaseAspect *aspect, - const QVariant &value, - const QString &settingsKey, - const QString &shortName, - const QString &labelText) -{ +void FakeVimSettings::setup(FvBaseAspect *aspect, const QVariant &value, const QString &settingsKey, + const QString &shortName, const QString &labelText) { aspect->setSettingsKey("FakeVim", settingsKey); aspect->setDefaultValue(value); #ifndef FAKEVIM_STANDALONE @@ -197,15 +175,13 @@ void FakeVimSettings::setup(FvBaseAspect *aspect, m_nameToAspect[longName] = aspect; m_aspectToName[aspect] = longName; } - if (!shortName.isEmpty()) - m_nameToAspect[shortName] = aspect; + if (!shortName.isEmpty()) m_nameToAspect[shortName] = aspect; } -FakeVimSettings *fakeVimSettings() -{ +FakeVimSettings *fakeVimSettings() { static FakeVimSettings s; return &s; } -} // namespace Internal -} // namespace FakeVim +} // namespace Internal +} // namespace FakeVim diff --git a/src/libraries/fakevim/fakevim/fakevimactions.h b/src/libraries/fakevim/fakevim/fakevimactions.h index 676bc7f9a..630d10fb6 100644 --- a/src/libraries/fakevim/fakevim/fakevimactions.h +++ b/src/libraries/fakevim/fakevim/fakevimactions.h @@ -28,9 +28,9 @@ #define FAKEVIM_STANDALONE #ifdef FAKEVIM_STANDALONE -//# include "private/fakevim_export.h" +// # include "private/fakevim_export.h" #else -# include +#include #endif #include @@ -43,9 +43,8 @@ namespace FakeVim { namespace Internal { #ifdef FAKEVIM_STANDALONE -class FvBaseAspect -{ -public: +class FvBaseAspect { + public: FvBaseAspect(); virtual ~FvBaseAspect() {} @@ -59,34 +58,30 @@ public: void setDisplayName(const QString &) {} void setToolTip(const QString &) {} -private: + private: QVariant m_value; QVariant m_defaultValue; QString m_settingsGroup; QString m_settingsKey; }; -class FvBoolAspect : public FvBaseAspect -{ -public: +class FvBoolAspect : public FvBaseAspect { + public: bool value() const { return FvBaseAspect::value().toBool(); } }; -class FvIntegerAspect : public FvBaseAspect -{ -public: +class FvIntegerAspect : public FvBaseAspect { + public: qint64 value() const { return FvBaseAspect::value().toLongLong(); } }; -class FvStringAspect : public FvBaseAspect -{ -public: +class FvStringAspect : public FvBaseAspect { + public: QString value() const { return FvBaseAspect::value().toString(); } }; -class FvAspectContainer : public FvBaseAspect -{ -public: +class FvAspectContainer : public FvBaseAspect { + public: }; #else @@ -99,11 +94,10 @@ using FvStringAspect = Utils::StringAspect; #endif -class FakeVimSettings final : public FvAspectContainer -{ +class FakeVimSettings final : public FvAspectContainer { Q_DECLARE_TR_FUNCTIONS(FakeVim) -public: + public: FakeVimSettings(); ~FakeVimSettings(); @@ -160,11 +154,9 @@ public: FvBoolAspect blinkingCursor; -private: - void setup(FvBaseAspect *aspect, const QVariant &value, - const QString &settingsKey, - const QString &shortName, - const QString &label); + private: + void setup(FvBaseAspect *aspect, const QVariant &value, const QString &settingsKey, + const QString &shortName, const QString &label); QHash m_nameToAspect; QHash m_aspectToName; @@ -172,5 +164,5 @@ private: FakeVimSettings *fakeVimSettings(); -} // namespace Internal -} // namespace FakeVim +} // namespace Internal +} // namespace FakeVim diff --git a/src/libraries/fakevim/fakevim/fakevimhandler.cpp b/src/libraries/fakevim/fakevim/fakevimhandler.cpp index 3e9b57904..91b66eb82 100644 --- a/src/libraries/fakevim/fakevim/fakevimhandler.cpp +++ b/src/libraries/fakevim/fakevim/fakevimhandler.cpp @@ -55,60 +55,58 @@ #include "fakevimhandler.h" -#include "fakevimactions.h" -#include "fakevimtr.h" - +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include +#include +#include +#include #include #include #include +#include +#include #include +#include +#include +#include #include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include - +#include +#include #include #include -#include #include +#include "fakevimactions.h" +#include "fakevimtr.h" + #define DEBUG_KEY 0 #if DEBUG_KEY -# define KEY_DEBUG(s) qDebug() << s +#define KEY_DEBUG(s) qDebug() << s #else -# define KEY_DEBUG(s) +#define KEY_DEBUG(s) #endif #define DEBUG_UNDO 0 #if DEBUG_UNDO -# define UNDO_DEBUG(s) qDebug() << "REV" << revision() << s +#define UNDO_DEBUG(s) qDebug() << "REV" << revision() << s #else -# define UNDO_DEBUG(s) +#define UNDO_DEBUG(s) #endif // Added by waqar144 // Purpose: We support Qt <= 5.8 #ifndef Q_FALLTHROUGH -# define Q_FALLTHROUGH() (void)0 +#define Q_FALLTHROUGH() (void)0 #endif namespace FakeVim { @@ -120,23 +118,22 @@ namespace Internal { // /////////////////////////////////////////////////////////////////////// -#define StartOfLine QTextCursor::StartOfLine -#define EndOfLine QTextCursor::EndOfLine -#define MoveAnchor QTextCursor::MoveAnchor -#define KeepAnchor QTextCursor::KeepAnchor -#define Up QTextCursor::Up -#define Down QTextCursor::Down -#define Right QTextCursor::Right -#define Left QTextCursor::Left -#define EndOfDocument QTextCursor::End +#define StartOfLine QTextCursor::StartOfLine +#define EndOfLine QTextCursor::EndOfLine +#define MoveAnchor QTextCursor::MoveAnchor +#define KeepAnchor QTextCursor::KeepAnchor +#define Up QTextCursor::Up +#define Down QTextCursor::Down +#define Right QTextCursor::Right +#define Left QTextCursor::Left +#define EndOfDocument QTextCursor::End #define StartOfDocument QTextCursor::Start -#define NextBlock QTextCursor::NextBlock +#define NextBlock QTextCursor::NextBlock #define ParagraphSeparator QChar::ParagraphSeparator #define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s) - #ifdef Q_OS_DARWIN #define ControlModifier Qt::MetaModifier #else @@ -150,18 +147,11 @@ static const QString vimMimeTextEncoded = "_VIMENC_TEXT"; using namespace Qt; /*! A \e Mode represents one of the basic modes of operation of FakeVim. -*/ + */ -enum Mode -{ - InsertMode, - ReplaceMode, - CommandMode, - ExMode -}; +enum Mode { InsertMode, ReplaceMode, CommandMode, ExMode }; -enum BlockInsertMode -{ +enum BlockInsertMode { NoneBlockInsertMode, AppendBlockInsertMode, AppendToEndOfLineBlockInsertMode, @@ -172,70 +162,57 @@ enum BlockInsertMode /*! A \e SubMode is used for things that require one more data item and are 'nested' behind a \l Mode. */ -enum SubMode -{ +enum SubMode { NoSubMode, - ChangeSubMode, // Used for c - DeleteSubMode, // Used for d - ExchangeSubMode, // Used for cx - DeleteSurroundingSubMode, // Used for ds - ChangeSurroundingSubMode, // Used for cs - AddSurroundingSubMode, // Used for ys - FilterSubMode, // Used for ! - IndentSubMode, // Used for = - RegisterSubMode, // Used for " - ShiftLeftSubMode, // Used for < - ShiftRightSubMode, // Used for > - CommentSubMode, // Used for gc - ReplaceWithRegisterSubMode, // Used for gr - InvertCaseSubMode, // Used for g~ - DownCaseSubMode, // Used for gu - UpCaseSubMode, // Used for gU - WindowSubMode, // Used for Ctrl-w - YankSubMode, // Used for y - ZSubMode, // Used for z - CapitalZSubMode, // Used for Z - ReplaceSubMode, // Used for r - MacroRecordSubMode, // Used for q - MacroExecuteSubMode, // Used for @ - CtrlVSubMode, // Used for Ctrl-v in insert mode - CtrlRSubMode // Used for Ctrl-r in insert mode + ChangeSubMode, // Used for c + DeleteSubMode, // Used for d + ExchangeSubMode, // Used for cx + DeleteSurroundingSubMode, // Used for ds + ChangeSurroundingSubMode, // Used for cs + AddSurroundingSubMode, // Used for ys + FilterSubMode, // Used for ! + IndentSubMode, // Used for = + RegisterSubMode, // Used for " + ShiftLeftSubMode, // Used for < + ShiftRightSubMode, // Used for > + CommentSubMode, // Used for gc + ReplaceWithRegisterSubMode, // Used for gr + InvertCaseSubMode, // Used for g~ + DownCaseSubMode, // Used for gu + UpCaseSubMode, // Used for gU + WindowSubMode, // Used for Ctrl-w + YankSubMode, // Used for y + ZSubMode, // Used for z + CapitalZSubMode, // Used for Z + ReplaceSubMode, // Used for r + MacroRecordSubMode, // Used for q + MacroExecuteSubMode, // Used for @ + CtrlVSubMode, // Used for Ctrl-v in insert mode + CtrlRSubMode // Used for Ctrl-r in insert mode }; /*! A \e SubSubMode is used for things that require one more data item and are 'nested' behind a \l SubMode. */ -enum SubSubMode -{ +enum SubSubMode { NoSubSubMode, - FtSubSubMode, // Used for f, F, t, T. - MarkSubSubMode, // Used for m. - BackTickSubSubMode, // Used for `. - TickSubSubMode, // Used for '. - TextObjectSubSubMode, // Used for thing like iw, aW, as etc. - ZSubSubMode, // Used for zj, zk - OpenSquareSubSubMode, // Used for [{, {(, [z - CloseSquareSubSubMode, // Used for ]}, ]), ]z - SearchSubSubMode, // Used for /, ? - SurroundSubSubMode, // Used for cs, ds, ys - SurroundWithFunctionSubSubMode, // Used for ys{motion}f - CtrlVUnicodeSubSubMode // Used for Ctrl-v based unicode input + FtSubSubMode, // Used for f, F, t, T. + MarkSubSubMode, // Used for m. + BackTickSubSubMode, // Used for `. + TickSubSubMode, // Used for '. + TextObjectSubSubMode, // Used for thing like iw, aW, as etc. + ZSubSubMode, // Used for zj, zk + OpenSquareSubSubMode, // Used for [{, {(, [z + CloseSquareSubSubMode, // Used for ]}, ]), ]z + SearchSubSubMode, // Used for /, ? + SurroundSubSubMode, // Used for cs, ds, ys + SurroundWithFunctionSubSubMode, // Used for ys{motion}f + CtrlVUnicodeSubSubMode // Used for Ctrl-v based unicode input }; -enum VisualMode -{ - NoVisualMode, - VisualCharMode, - VisualLineMode, - VisualBlockMode -}; +enum VisualMode { NoVisualMode, VisualCharMode, VisualLineMode, VisualBlockMode }; -enum MoveType -{ - MoveExclusive, - MoveInclusive, - MoveLineWise -}; +enum MoveType { MoveExclusive, MoveInclusive, MoveLineWise }; /*! \enum RangeMode @@ -259,54 +236,50 @@ enum MoveType of these lines. */ -enum EventResult -{ +enum EventResult { EventHandled, EventUnhandled, - EventCancelled, // Event is handled but a sub mode was cancelled. + EventCancelled, // Event is handled but a sub mode was cancelled. EventPassedToCore }; -struct CursorPosition -{ +struct CursorPosition { CursorPosition() = default; CursorPosition(int block, int column) : line(block), column(column) {} explicit CursorPosition(const QTextCursor &tc) : line(tc.block().blockNumber()), column(tc.positionInBlock()) {} - CursorPosition(const QTextDocument *document, int position) - { + CursorPosition(const QTextDocument *document, int position) { QTextBlock block = document->findBlock(position); line = block.blockNumber(); column = position - block.position(); } bool isValid() const { return line >= 0 && column >= 0; } - bool operator>(const CursorPosition &other) const - { return line > other.line || column > other.column; } - bool operator==(const CursorPosition &other) const - { return line == other.line && column == other.column; } + bool operator>(const CursorPosition &other) const { + return line > other.line || column > other.column; + } + bool operator==(const CursorPosition &other) const { + return line == other.line && column == other.column; + } bool operator!=(const CursorPosition &other) const { return !operator==(other); } - int line = -1; // Line in document (from 0, folded lines included). - int column = -1; // Position on line. + int line = -1; // Line in document (from 0, folded lines included). + int column = -1; // Position on line. }; -QDebug operator<<(QDebug ts, const CursorPosition &pos) -{ +QDebug operator<<(QDebug ts, const CursorPosition &pos) { return ts << "(line: " << pos.line << ", column: " << pos.column << ")"; } // vi style configuration -class Mark -{ -public: +class Mark { + public: Mark(const CursorPosition &pos = CursorPosition(), const QString &fileName = QString()) : m_position(pos), m_fileName(fileName) {} bool isValid() const { return m_position.isValid(); } - bool isLocal(const QString &localFileName) const - { + bool isLocal(const QString &localFileName) const { return m_fileName.isEmpty() || m_fileName == localFileName; } @@ -314,8 +287,7 @@ public: * If saved line number is too big, mark position is at the end of document. * If line number is in document but column is too big, mark position is at the end of line. */ - CursorPosition position(const QTextDocument *document) const - { + CursorPosition position(const QTextDocument *document) const { QTextBlock block = document->findBlockByNumber(m_position.line); CursorPosition pos; if (block.isValid()) { @@ -335,19 +307,21 @@ public: void setFileName(const QString &fileName) { m_fileName = fileName; } -private: + private: CursorPosition m_position; QString m_fileName; }; using Marks = QHash; -struct State -{ +struct State { State() = default; State(int revision, const CursorPosition &position, const Marks &marks, - VisualMode lastVisualMode, bool lastVisualModeInverted) : revision(revision), - position(position), marks(marks), lastVisualMode(lastVisualMode), - lastVisualModeInverted(lastVisualModeInverted) {} + VisualMode lastVisualMode, bool lastVisualModeInverted) + : revision(revision), + position(position), + marks(marks), + lastVisualMode(lastVisualMode), + lastVisualModeInverted(lastVisualModeInverted) {} bool isValid() const { return position.isValid(); } @@ -358,20 +332,17 @@ struct State bool lastVisualModeInverted = false; }; -struct Column -{ +struct Column { Column(int p, int l) : physical(p), logical(l) {} - int physical; // Number of characters in the data. - int logical; // Column on screen. + int physical; // Number of characters in the data. + int logical; // Column on screen. }; -QDebug operator<<(QDebug ts, const Column &col) -{ +QDebug operator<<(QDebug ts, const Column &col) { return ts << "(p: " << col.physical << ", l: " << col.logical << ")"; } -struct Register -{ +struct Register { Register() = default; Register(const QString &c) : contents(c) {} Register(const QString &c, RangeMode m) : contents(c), rangemode(m) {} @@ -379,35 +350,27 @@ struct Register RangeMode rangemode = RangeCharMode; }; -QDebug operator<<(QDebug ts, const Register ®) -{ - return ts << reg.contents; -} +QDebug operator<<(QDebug ts, const Register ®) { return ts << reg.contents; } -struct SearchData -{ +struct SearchData { QString needle; bool forward = true; bool highlightMatches = true; }; -static QString replaceTildeWithHome(QString str) -{ +static QString replaceTildeWithHome(QString str) { str.replace("~", QDir::homePath()); return str; } // If string begins with given prefix remove it with trailing spaces and return true. -static bool eatString(const QString &prefix, QString *str) -{ - if (!str->startsWith(prefix)) - return false; +static bool eatString(const QString &prefix, QString *str) { + if (!str->startsWith(prefix)) return false; *str = str->mid(prefix.size()).trimmed(); return true; } -static QString vimPatternToQtPattern_QString(const QString &needle, bool &initIgnoreCase) -{ +static QString vimPatternToQtPattern_QString(const QString &needle, bool &initIgnoreCase) { /* Transformations (Vim regexp -> QRegularExpression): * \a -> [A-Za-z] * \A -> [^A-Za-z] @@ -441,8 +404,8 @@ static QString vimPatternToQtPattern_QString(const QString &needle, bool &initIg // FIXME: Option smartcase should be used only if search was typed by user. const bool ignoreCaseOption = fakeVimSettings()->ignoreCase.value(); const bool smartCaseOption = fakeVimSettings()->smartCase.value(); - const bool initialIgnoreCase = ignoreCaseOption - && !(smartCaseOption && needle.contains(QRegularExpression("[A-Z]"))); + const bool initialIgnoreCase = + ignoreCaseOption && !(smartCaseOption && needle.contains(QRegularExpression("[A-Z]"))); bool ignorecase = initialIgnoreCase; @@ -559,7 +522,7 @@ static QString vimPatternToQtPattern_QString(const QString &needle, bool &initIg return pattern; } -#if QT_VERSION < QT_VERSION_CHECK(5,5,0) +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) static QRegExp vimPatternToQtPattern(const QString &needle) #else static QRegularExpression vimPatternToQtPattern(const QString &needle) @@ -568,7 +531,7 @@ static QRegularExpression vimPatternToQtPattern(const QString &needle) bool initialIgnoreCase = false; const auto pattern = vimPatternToQtPattern_QString(needle, initialIgnoreCase); -#if QT_VERSION < QT_VERSION_CHECK(5,5,0) +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) return QRegExp(pattern, initialIgnoreCase ? Qt::CaseInsensitive : Qt::CaseSensitive); #else return QRegularExpression(pattern, initialIgnoreCase ? QRegularExpression::CaseInsensitiveOption @@ -576,21 +539,19 @@ static QRegularExpression vimPatternToQtPattern(const QString &needle) #endif } -static QRegularExpression vimPatternToQtPattern_QRegularExpression(const QString &needle) -{ +static QRegularExpression vimPatternToQtPattern_QRegularExpression(const QString &needle) { bool initialIgnoreCase = false; const auto pattern = vimPatternToQtPattern_QString(needle, initialIgnoreCase); return QRegularExpression(pattern, initialIgnoreCase ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption); } -static bool afterEndOfLine(const QTextDocument *doc, int position) -{ - return doc->characterAt(position) == ParagraphSeparator - && doc->findBlock(position).length() > 1; +static bool afterEndOfLine(const QTextDocument *doc, int position) { + return doc->characterAt(position) == ParagraphSeparator && + doc->findBlock(position).length() > 1; } -#if QT_VERSION < QT_VERSION_CHECK(5,5,0) +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) static void searchForward(QTextCursor *tc, const QRegExp &needleExp, int *repeat) #else static void searchForward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat) @@ -600,9 +561,8 @@ static void searchForward(QTextCursor *tc, const QRegularExpression &needleExp, const int startPos = tc->position(); QTextDocument::FindFlags flags = {}; -#if QT_VERSION < QT_VERSION_CHECK(5,5,0) - if (needleExp.caseSensitivity()) - flags |= QTextDocument::FindCaseSensitively; +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) + if (needleExp.caseSensitivity()) flags |= QTextDocument::FindCaseSensitively; #else if (!(needleExp.patternOptions() & QRegularExpression::CaseInsensitiveOption)) flags |= QTextDocument::FindCaseSensitively; @@ -614,36 +574,28 @@ static void searchForward(QTextCursor *tc, const QRegularExpression &needleExp, // forward to current position *tc = doc->find(needleExp, *tc, flags); while (!tc->isNull() && tc->anchor() < startPos) { - if (!tc->hasSelection()) - tc->movePosition(Right); - if (tc->atBlockEnd()) - tc->movePosition(NextBlock); + if (!tc->hasSelection()) tc->movePosition(Right); + if (tc->atBlockEnd()) tc->movePosition(NextBlock); *tc = doc->find(needleExp, *tc, flags); } - if (tc->isNull()) - return; + if (tc->isNull()) return; --*repeat; while (*repeat > 0) { - if (!tc->hasSelection()) - tc->movePosition(Right); - if (tc->atBlockEnd()) - tc->movePosition(NextBlock); + if (!tc->hasSelection()) tc->movePosition(Right); + if (tc->atBlockEnd()) tc->movePosition(NextBlock); *tc = doc->find(needleExp, *tc, flags); - if (tc->isNull()) - return; + if (tc->isNull()) return; --*repeat; } - if (!tc->isNull() && afterEndOfLine(doc, tc->anchor())) - tc->movePosition(Left); + if (!tc->isNull() && afterEndOfLine(doc, tc->anchor())) tc->movePosition(Left); } -#if QT_VERSION < QT_VERSION_CHECK(5,5,0) -static void searchBackward(QTextCursor *tc, const QRegExp &needleExp, int *repeat) -{ +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) +static void searchBackward(QTextCursor *tc, const QRegExp &needleExp, int *repeat) { // Search from beginning of line so that matched text is the same. QTextBlock block = tc->block(); QString line = block.text(); @@ -653,25 +605,21 @@ static void searchBackward(QTextCursor *tc, const QRegExp &needleExp, int *repea --*repeat; const int offset = i + qMax(1, needleExp.matchedLength()); i = needleExp.indexIn(line, offset); - if (i == line.size()) - i = -1; + if (i == line.size()) i = -1; } - if (i == tc->positionInBlock()) - --*repeat; + if (i == tc->positionInBlock()) --*repeat; while (*repeat > 0) { block = block.previous(); - if (!block.isValid()) - break; + if (!block.isValid()) break; line = block.text(); i = needleExp.indexIn(line, 0); while (i != -1) { --*repeat; const int offset = i + qMax(1, needleExp.matchedLength()); i = needleExp.indexIn(line, offset); - if (i == line.size()) - i = -1; + if (i == line.size()) i = -1; } } @@ -680,7 +628,7 @@ static void searchBackward(QTextCursor *tc, const QRegExp &needleExp, int *repea return; } - i = needleExp.indexIn(line, 0); + i = needleExp.indexIn(line, 0); while (*repeat < 0) { const int offset = i + qMax(1, needleExp.matchedLength()); i = needleExp.indexIn(line, offset); @@ -690,8 +638,7 @@ static void searchBackward(QTextCursor *tc, const QRegExp &needleExp, int *repea tc->setPosition(tc->position() + needleExp.matchedLength(), KeepAnchor); } #else -static void searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat) -{ +static void searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat) { // Search from beginning of line so that matched text is the same. QTextBlock block = tc->block(); QString line = block.text(); @@ -702,25 +649,21 @@ static void searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, --*repeat; const int offset = i + qMax(1, match.capturedLength()); i = line.indexOf(needleExp, offset, &match); - if (i == line.size()) - i = -1; + if (i == line.size()) i = -1; } - if (i == tc->positionInBlock()) - --*repeat; + if (i == tc->positionInBlock()) --*repeat; while (*repeat > 0) { block = block.previous(); - if (!block.isValid()) - break; + if (!block.isValid()) break; line = block.text(); i = line.indexOf(needleExp, 0, &match); while (i != -1) { --*repeat; const int offset = i + qMax(1, match.capturedLength()); i = line.indexOf(needleExp, offset, &match); - if (i == line.size()) - i = -1; + if (i == line.size()) i = -1; } } @@ -741,9 +684,8 @@ static void searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, #endif // Commands [[, [] -static void bracketSearchBackward(QTextCursor *tc, const QString &needleExp, int repeat) -{ -#if QT_VERSION < QT_VERSION_CHECK(5,5,0) +static void bracketSearchBackward(QTextCursor *tc, const QString &needleExp, int repeat) { +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) const QRegExp re(needleExp); #else const QRegularExpression re(needleExp); @@ -751,16 +693,14 @@ static void bracketSearchBackward(QTextCursor *tc, const QString &needleExp, int QTextCursor tc2 = *tc; tc2.setPosition(tc2.position() - 1); searchBackward(&tc2, re, &repeat); - if (repeat <= 1) - tc->setPosition(tc2.isNull() ? 0 : tc2.position(), KeepAnchor); + if (repeat <= 1) tc->setPosition(tc2.isNull() ? 0 : tc2.position(), KeepAnchor); } // Commands ][, ]] // When ]] is used after an operator, then also stops below a '}' in the first column. static void bracketSearchForward(QTextCursor *tc, const QString &needleExp, int repeat, - bool searchWithCommand) -{ -#if QT_VERSION < QT_VERSION_CHECK(5,5,0) + bool searchWithCommand) { +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) QRegExp re(searchWithCommand ? QStringLiteral("^\\}|^\\{") : needleExp); #else QRegularExpression re(searchWithCommand ? QStringLiteral("^\\}|^\\{") : needleExp); @@ -776,31 +716,32 @@ static void bracketSearchForward(QTextCursor *tc, const QString &needleExp, int tc->setPosition(tc2.position() - 1, KeepAnchor); if (searchWithCommand && tc->document()->characterAt(tc->position()).unicode() == '}') { QTextBlock block = tc->block().next(); - if (block.isValid()) - tc->setPosition(block.position(), KeepAnchor); + if (block.isValid()) tc->setPosition(block.position(), KeepAnchor); } } } } -static char backslashed(char t) -{ +static char backslashed(char t) { switch (t) { - case 'e': return 27; - case 't': return '\t'; - case 'r': return '\r'; - case 'n': return '\n'; - case 'b': return 8; + case 'e': + return 27; + case 't': + return '\t'; + case 'r': + return '\r'; + case 'n': + return '\n'; + case 'b': + return 8; } return t; } -enum class Modifier {NONE,UPPERCASE,LOWERCASE}; +enum class Modifier { NONE, UPPERCASE, LOWERCASE }; -static QString applyReplacementLetterCases(QString repl, - Modifier &toggledModifier, - Modifier &nextCharacterModifier) -{ +static QString applyReplacementLetterCases(QString repl, Modifier &toggledModifier, + Modifier &nextCharacterModifier) { if (toggledModifier == Modifier::UPPERCASE) repl = repl.toUpper(); else if (toggledModifier == Modifier::LOWERCASE) @@ -816,19 +757,15 @@ static QString applyReplacementLetterCases(QString repl, return repl; } -static QChar applyReplacementLetterCases(QChar repl, - Modifier &toggledModifier, - Modifier &nextCharacterModifier) -{ - if (nextCharacterModifier == Modifier::UPPERCASE){ +static QChar applyReplacementLetterCases(QChar repl, Modifier &toggledModifier, + Modifier &nextCharacterModifier) { + if (nextCharacterModifier == Modifier::UPPERCASE) { nextCharacterModifier = Modifier::NONE; return repl.toUpper(); - } - else if (nextCharacterModifier == Modifier::LOWERCASE) { + } else if (nextCharacterModifier == Modifier::LOWERCASE) { nextCharacterModifier = Modifier::NONE; return repl.toLower(); - } - else if (toggledModifier == Modifier::UPPERCASE) + } else if (toggledModifier == Modifier::UPPERCASE) return repl.toUpper(); else if (toggledModifier == Modifier::LOWERCASE) return repl.toLower(); @@ -836,26 +773,21 @@ static QChar applyReplacementLetterCases(QChar repl, return repl; } -static bool substituteText(QString *text, - const QRegularExpression &pattern, - const QString &replacement, - bool global) -{ +static bool substituteText(QString *text, const QRegularExpression &pattern, + const QString &replacement, bool global) { bool substituted = false; int pos = 0; int right = -1; while (true) { const QRegularExpressionMatch match = pattern.match(*text, pos); - if (!match.hasMatch()) - break; + if (!match.hasMatch()) break; pos = match.capturedStart(); // ensure that substitution is advancing towards end of line if (right == text->size() - pos) { ++pos; - if (pos == text->size()) - break; + if (pos == text->size()) break; continue; } @@ -875,9 +807,7 @@ static bool substituteText(QString *text, if (c.isDigit()) { if (c.digitValue() <= match.lastCapturedIndex()) { repl += applyReplacementLetterCases(match.captured(c.digitValue()), - toggledModifier, - nextCharacterModifier); - + toggledModifier, nextCharacterModifier); } } else if (c == 'u') { nextCharacterModifier = Modifier::UPPERCASE; @@ -897,8 +827,7 @@ static bool substituteText(QString *text, if (c == '\\') escape = true; else if (c == '&') - repl += applyReplacementLetterCases(match.captured(0), - toggledModifier, + repl += applyReplacementLetterCases(match.captured(0), toggledModifier, nextCharacterModifier); else repl += applyReplacementLetterCases(c, toggledModifier, nextCharacterModifier); @@ -907,25 +836,21 @@ static bool substituteText(QString *text, text->replace(pos, matched.size(), repl); pos += (repl.isEmpty() && matched.isEmpty()) ? 1 : repl.size(); - if (pos >= text->size() || !global) - break; + if (pos >= text->size() || !global) break; } return substituted; } -static int findUnescaped(QChar c, const QString &line, int from) -{ +static int findUnescaped(QChar c, const QString &line, int from) { for (int i = from; i < line.size(); ++i) { - if (line.at(i) == c && (i == 0 || line.at(i - 1) != '\\')) - return i; + if (line.at(i) == c && (i == 0 || line.at(i - 1) != '\\')) return i; } return -1; } static void setClipboardData(const QString &content, RangeMode mode, - QClipboard::Mode clipboardMode) -{ + QClipboard::Mode clipboardMode) { QClipboard *clipboard = QApplication::clipboard(); char vimRangeMode = mode; @@ -946,8 +871,7 @@ static void setClipboardData(const QString &content, RangeMode mode, clipboard->setMimeData(data, clipboardMode); } -static QByteArray toLocalEncoding(const QString &text) -{ +static QByteArray toLocalEncoding(const QString &text) { #if defined(Q_OS_WIN) return QString(text).replace("\n", "\r\n").toLocal8Bit(); #else @@ -955,8 +879,7 @@ static QByteArray toLocalEncoding(const QString &text) #endif } -static QString fromLocalEncoding(const QByteArray &data) -{ +static QString fromLocalEncoding(const QByteArray &data) { #if defined(Q_OS_WIN) return QString::fromLocal8Bit(data).replace("\n", "\r\n"); #else @@ -964,8 +887,7 @@ static QString fromLocalEncoding(const QByteArray &data) #endif } -static QString getProcessOutput(const QString &command, const QString &input) -{ +static QString getProcessOutput(const QString &command, const QString &input) { // ensure the executable exists in some standard path and isn't random const auto fullCmdPath = QStandardPaths::findExecutable(command); if (fullCmdPath.isEmpty()) { @@ -973,7 +895,7 @@ static QString getProcessOutput(const QString &command, const QString &input) } QProcess proc; -#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) QStringList arguments = QProcess::splitCommand(command); QString executable = arguments.takeFirst(); proc.start(executable, arguments); @@ -991,107 +913,102 @@ static QString getProcessOutput(const QString &command, const QString &input) return fromLocalEncoding(proc.readAllStandardOutput()); } -static const QMap &vimKeyNames() -{ - static const QMap k = { - // FIXME: Should be value of mapleader. - {"LEADER", Key_Backslash}, +static const QMap &vimKeyNames() { + static const QMap k = {// FIXME: Should be value of mapleader. + {"LEADER", Key_Backslash}, - {"SPACE", Key_Space}, - {"TAB", Key_Tab}, - {"NL", Key_Return}, - {"NEWLINE", Key_Return}, - {"LINEFEED", Key_Return}, - {"LF", Key_Return}, - {"CR", Key_Return}, - {"RETURN", Key_Return}, - {"ENTER", Key_Return}, - {"BS", Key_Backspace}, - {"BACKSPACE", Key_Backspace}, - {"ESC", Key_Escape}, - {"BAR", Key_Bar}, - {"BSLASH", Key_Backslash}, - {"DEL", Key_Delete}, - {"DELETE", Key_Delete}, - {"KDEL", Key_Delete}, - {"UP", Key_Up}, - {"DOWN", Key_Down}, - {"LEFT", Key_Left}, - {"RIGHT", Key_Right}, + {"SPACE", Key_Space}, + {"TAB", Key_Tab}, + {"NL", Key_Return}, + {"NEWLINE", Key_Return}, + {"LINEFEED", Key_Return}, + {"LF", Key_Return}, + {"CR", Key_Return}, + {"RETURN", Key_Return}, + {"ENTER", Key_Return}, + {"BS", Key_Backspace}, + {"BACKSPACE", Key_Backspace}, + {"ESC", Key_Escape}, + {"BAR", Key_Bar}, + {"BSLASH", Key_Backslash}, + {"DEL", Key_Delete}, + {"DELETE", Key_Delete}, + {"KDEL", Key_Delete}, + {"UP", Key_Up}, + {"DOWN", Key_Down}, + {"LEFT", Key_Left}, + {"RIGHT", Key_Right}, - {"LT", Key_Less}, - {"GT", Key_Greater}, + {"LT", Key_Less}, + {"GT", Key_Greater}, - {"F1", Key_F1}, - {"F2", Key_F2}, - {"F3", Key_F3}, - {"F4", Key_F4}, - {"F5", Key_F5}, - {"F6", Key_F6}, - {"F7", Key_F7}, - {"F8", Key_F8}, - {"F9", Key_F9}, - {"F10", Key_F10}, + {"F1", Key_F1}, + {"F2", Key_F2}, + {"F3", Key_F3}, + {"F4", Key_F4}, + {"F5", Key_F5}, + {"F6", Key_F6}, + {"F7", Key_F7}, + {"F8", Key_F8}, + {"F9", Key_F9}, + {"F10", Key_F10}, - {"F11", Key_F11}, - {"F12", Key_F12}, - {"F13", Key_F13}, - {"F14", Key_F14}, - {"F15", Key_F15}, - {"F16", Key_F16}, - {"F17", Key_F17}, - {"F18", Key_F18}, - {"F19", Key_F19}, - {"F20", Key_F20}, + {"F11", Key_F11}, + {"F12", Key_F12}, + {"F13", Key_F13}, + {"F14", Key_F14}, + {"F15", Key_F15}, + {"F16", Key_F16}, + {"F17", Key_F17}, + {"F18", Key_F18}, + {"F19", Key_F19}, + {"F20", Key_F20}, - {"F21", Key_F21}, - {"F22", Key_F22}, - {"F23", Key_F23}, - {"F24", Key_F24}, - {"F25", Key_F25}, - {"F26", Key_F26}, - {"F27", Key_F27}, - {"F28", Key_F28}, - {"F29", Key_F29}, - {"F30", Key_F30}, + {"F21", Key_F21}, + {"F22", Key_F22}, + {"F23", Key_F23}, + {"F24", Key_F24}, + {"F25", Key_F25}, + {"F26", Key_F26}, + {"F27", Key_F27}, + {"F28", Key_F28}, + {"F29", Key_F29}, + {"F30", Key_F30}, - {"F31", Key_F31}, - {"F32", Key_F32}, - {"F33", Key_F33}, - {"F34", Key_F34}, - {"F35", Key_F35}, + {"F31", Key_F31}, + {"F32", Key_F32}, + {"F33", Key_F33}, + {"F34", Key_F34}, + {"F35", Key_F35}, - {"INSERT", Key_Insert}, - {"INS", Key_Insert}, - {"KINSERT", Key_Insert}, - {"HOME", Key_Home}, - {"END", Key_End}, - {"PAGEUP", Key_PageUp}, - {"PAGEDOWN", Key_PageDown}, + {"INSERT", Key_Insert}, + {"INS", Key_Insert}, + {"KINSERT", Key_Insert}, + {"HOME", Key_Home}, + {"END", Key_End}, + {"PAGEUP", Key_PageUp}, + {"PAGEDOWN", Key_PageDown}, - {"KPLUS", Key_Plus}, - {"KMINUS", Key_Minus}, - {"KDIVIDE", Key_Slash}, - {"KMULTIPLY", Key_Asterisk}, - {"KENTER", Key_Enter}, - {"KPOINT", Key_Period}, + {"KPLUS", Key_Plus}, + {"KMINUS", Key_Minus}, + {"KDIVIDE", Key_Slash}, + {"KMULTIPLY", Key_Asterisk}, + {"KENTER", Key_Enter}, + {"KPOINT", Key_Period}, - {"CAPS", Key_CapsLock}, - {"NUM", Key_NumLock}, - {"SCROLL", Key_ScrollLock}, - {"ALTGR", Key_AltGr} - }; + {"CAPS", Key_CapsLock}, + {"NUM", Key_NumLock}, + {"SCROLL", Key_ScrollLock}, + {"ALTGR", Key_AltGr}}; return k; } -static bool isOnlyControlModifier(const Qt::KeyboardModifiers &mods) -{ +static bool isOnlyControlModifier(const Qt::KeyboardModifiers &mods) { return (mods ^ ControlModifier) == Qt::NoModifier; } -static bool isAcceptableModifier(const Qt::KeyboardModifiers &mods) -{ +static bool isAcceptableModifier(const Qt::KeyboardModifiers &mods) { if (mods & ControlModifier) { // Generally, CTRL is not fine, except in combination with ALT. // See QTCREATORBUG-24673 @@ -1100,50 +1017,37 @@ static bool isAcceptableModifier(const Qt::KeyboardModifiers &mods) return true; } - Range::Range(int b, int e, RangeMode m) - : beginPos(qMin(b, e)), endPos(qMax(b, e)), rangemode(m) -{} + : beginPos(qMin(b, e)), endPos(qMax(b, e)), rangemode(m) {} -QString Range::toString() const -{ +QString Range::toString() const { return QStringLiteral("%1-%2 (mode: %3)").arg(beginPos).arg(endPos).arg(rangemode); } -bool Range::isValid() const -{ - return beginPos >= 0 && endPos >= 0; -} +bool Range::isValid() const { return beginPos >= 0 && endPos >= 0; } -QDebug operator<<(QDebug ts, const Range &range) -{ +QDebug operator<<(QDebug ts, const Range &range) { return ts << '[' << range.beginPos << ',' << range.endPos << ']'; } - ExCommand::ExCommand(const QString &c, const QString &a, const Range &r) - : cmd(c), args(a), range(r) -{} + : cmd(c), args(a), range(r) {} -bool ExCommand::matches(const QString &min, const QString &full) const -{ +bool ExCommand::matches(const QString &min, const QString &full) const { return cmd.startsWith(min) && full.startsWith(cmd); } -QDebug operator<<(QDebug ts, const ExCommand &cmd) -{ +QDebug operator<<(QDebug ts, const ExCommand &cmd) { return ts << cmd.cmd << ' ' << cmd.args << ' ' << cmd.range; } -QDebug operator<<(QDebug ts, const QList &sels) -{ +QDebug operator<<(QDebug ts, const QList &sels) { foreach (const QTextEdit::ExtraSelection &sel, sels) ts << "SEL: " << sel.cursor.anchor() << sel.cursor.position(); return ts; } -QString quoteUnprintable(const QString &ba) -{ +QString quoteUnprintable(const QString &ba) { QString res; for (int i = 0, n = ba.size(); i != n; ++i) { const QChar c = ba.at(i); @@ -1158,38 +1062,31 @@ QString quoteUnprintable(const QString &ba) return res; } -static bool startsWithWhitespace(const QString &str, int col) -{ +static bool startsWithWhitespace(const QString &str, int col) { if (col > str.size()) { qWarning("Wrong column"); return false; } for (int i = 0; i < col; ++i) { uint u = str.at(i).unicode(); - if (u != ' ' && u != '\t') - return false; + if (u != ' ' && u != '\t') return false; } return true; } -inline QString msgMarkNotSet(const QString &text) -{ +inline QString msgMarkNotSet(const QString &text) { return Tr::tr("Mark \"%1\" not set.").arg(text); } -class Input -{ -public: +class Input { + public: // Remove some extra "information" on Mac. - static Qt::KeyboardModifiers cleanModifier(Qt::KeyboardModifiers m) - { + static Qt::KeyboardModifiers cleanModifier(Qt::KeyboardModifiers m) { return m & ~Qt::KeypadModifier; } Input() = default; - explicit Input(QChar x) - : m_key(x.unicode()), m_xkey(x.unicode()), m_text(x) - { + explicit Input(QChar x) : m_key(x.unicode()), m_xkey(x.unicode()), m_text(x) { if (x.isUpper()) m_modifiers = Qt::ShiftModifier; else if (x.isLower()) @@ -1197,8 +1094,7 @@ public: } Input(int k, Qt::KeyboardModifiers m, const QString &t = QString()) - : m_key(k), m_modifiers(cleanModifier(m)), m_text(t) - { + : m_key(k), m_modifiers(cleanModifier(m)), m_text(t) { if (m_text.size() == 1) { QChar x = m_text.at(0); @@ -1231,94 +1127,55 @@ public: m_xkey = (m_text.size() == 1 ? m_text.at(0).unicode() : m_key); } - bool isValid() const - { - return m_key != 0 || !m_text.isNull(); + bool isValid() const { return m_key != 0 || !m_text.isNull(); } + + bool isDigit() const { return m_xkey >= '0' && m_xkey <= '9'; } + + bool isKey(int c) const { return !m_modifiers && m_key == c; } + + bool isBackspace() const { return m_key == Key_Backspace || isControl('h'); } + + bool isReturn() const { return m_key == '\n' || m_key == Key_Return || m_key == Key_Enter; } + + bool isEscape() const { + return isKey(Key_Escape) || isShift(Key_Escape) || isKey(27) || isShift(27) || + isControl('c') || isControl(Key_BracketLeft); } - bool isDigit() const - { - return m_xkey >= '0' && m_xkey <= '9'; + bool is(int c) const { return m_xkey == c && isAcceptableModifier(m_modifiers); } + + bool isControl() const { return isOnlyControlModifier(m_modifiers); } + + bool isControl(int c) const { + return isControl() && + (m_xkey == c || m_xkey + 32 == c || m_xkey + 64 == c || m_xkey + 96 == c); } - bool isKey(int c) const - { - return !m_modifiers && m_key == c; - } + bool isShift() const { return m_modifiers & Qt::ShiftModifier; } - bool isBackspace() const - { - return m_key == Key_Backspace || isControl('h'); - } + bool isShift(int c) const { return isShift() && m_xkey == c; } - bool isReturn() const - { - return m_key == '\n' || m_key == Key_Return || m_key == Key_Enter; - } - - bool isEscape() const - { - return isKey(Key_Escape) || isShift(Key_Escape) || isKey(27) || isShift(27) || isControl('c') - || isControl(Key_BracketLeft); - } - - bool is(int c) const - { - return m_xkey == c && isAcceptableModifier(m_modifiers); - } - - bool isControl() const - { - return isOnlyControlModifier(m_modifiers); - } - - bool isControl(int c) const - { - return isControl() - && (m_xkey == c || m_xkey + 32 == c || m_xkey + 64 == c || m_xkey + 96 == c); - } - - bool isShift() const - { - return m_modifiers & Qt::ShiftModifier; - } - - bool isShift(int c) const - { - return isShift() && m_xkey == c; - } - - bool operator<(const Input &a) const - { - if (m_key != a.m_key) - return m_key < a.m_key; + bool operator<(const Input &a) const { + if (m_key != a.m_key) return m_key < a.m_key; // Text for some mapped key cannot be determined (e.g. ) so if text is not set for // one of compared keys ignore it. - if (!m_text.isEmpty() && !a.m_text.isEmpty() && m_text != " ") - return m_text < a.m_text; + if (!m_text.isEmpty() && !a.m_text.isEmpty() && m_text != " ") return m_text < a.m_text; return m_modifiers < a.m_modifiers; } - bool operator==(const Input &a) const - { - return !(*this < a || a < *this); - } + bool operator==(const Input &a) const { return !(*this < a || a < *this); } bool operator!=(const Input &a) const { return !operator==(a); } QString text() const { return m_text; } - QChar asChar() const - { - return (m_text.size() == 1 ? m_text.at(0) : QChar()); - } + QChar asChar() const { return (m_text.size() == 1 ? m_text.at(0) : QChar()); } - int toInt(bool *ok, int base) const - { + int toInt(bool *ok, int base) const { const int uc = asChar().unicode(); int res; if ('0' <= uc && uc <= '9') - res = uc -'0'; + res = uc - '0'; else if ('a' <= uc && uc <= 'z') res = 10 + uc - 'a'; else if ('A' <= uc && uc <= 'Z') @@ -1334,21 +1191,15 @@ public: Qt::KeyboardModifiers modifiers() const { return m_modifiers; } // Return raw character for macro recording or dot command. - QChar raw() const - { - if (m_key == Key_Tab) - return '\t'; - if (m_key == Key_Return) - return '\n'; - if (m_key == Key_Escape) - return QChar(27); + QChar raw() const { + if (m_key == Key_Tab) return '\t'; + if (m_key == Key_Return) return '\n'; + if (m_key == Key_Escape) return QChar(27); return QChar(m_xkey); } - QString toString() const - { - if (!m_text.isEmpty()) - return QString(m_text).replace("<", ""); + QString toString() const { + if (!m_text.isEmpty()) return QString(m_text).replace("<", ""); QString key = vimKeyNames().key(m_key); bool namedKey = !key.isEmpty(); @@ -1364,10 +1215,8 @@ public: bool shift = isShift(); bool ctrl = isControl(); - if (shift) - key.prepend("S-"); - if (ctrl) - key.prepend("C-"); + if (shift) key.prepend("S-"); + if (ctrl) key.prepend("C-"); if (namedKey || shift || ctrl) { key.prepend('<'); @@ -1377,13 +1226,11 @@ public: return key; } - QDebug dump(QDebug ts) const - { - return ts << m_key << '-' << m_modifiers << '-' - << quoteUnprintable(m_text); + QDebug dump(QDebug ts) const { + return ts << m_key << '-' << m_modifiers << '-' << quoteUnprintable(m_text); } -private: + private: int m_key = 0; int m_xkey = 0; Qt::KeyboardModifiers m_modifiers = NoModifier; @@ -1393,86 +1240,57 @@ private: // mapping to (do nothing) static const Input Nop(-1, Qt::KeyboardModifiers(-1), QString()); -static SubMode letterCaseModeFromInput(const Input &input) -{ - if (input.is('~')) - return InvertCaseSubMode; - if (input.is('u')) - return DownCaseSubMode; - if (input.is('U')) - return UpCaseSubMode; +static SubMode letterCaseModeFromInput(const Input &input) { + if (input.is('~')) return InvertCaseSubMode; + if (input.is('u')) return DownCaseSubMode; + if (input.is('U')) return UpCaseSubMode; return NoSubMode; } -static SubMode indentModeFromInput(const Input &input) -{ - if (input.is('<')) - return ShiftLeftSubMode; - if (input.is('>')) - return ShiftRightSubMode; - if (input.is('=')) - return IndentSubMode; +static SubMode indentModeFromInput(const Input &input) { + if (input.is('<')) return ShiftLeftSubMode; + if (input.is('>')) return ShiftRightSubMode; + if (input.is('=')) return IndentSubMode; return NoSubMode; } -static SubMode changeDeleteYankModeFromInput(const Input &input) -{ - if (input.is('c')) - return ChangeSubMode; - if (input.is('d')) - return DeleteSubMode; - if (input.is('y')) - return YankSubMode; +static SubMode changeDeleteYankModeFromInput(const Input &input) { + if (input.is('c')) return ChangeSubMode; + if (input.is('d')) return DeleteSubMode; + if (input.is('y')) return YankSubMode; return NoSubMode; } -QString dotCommandFromSubMode(SubMode submode) -{ - if (submode == ChangeSubMode) - return QLatin1String("c"); - if (submode == DeleteSubMode) - return QLatin1String("d"); - if (submode == CommentSubMode) - return QLatin1String("gc"); - if (submode == DeleteSurroundingSubMode) - return QLatin1String("ds"); - if (submode == ChangeSurroundingSubMode) - return QLatin1String("c"); - if (submode == AddSurroundingSubMode) - return QLatin1String("y"); - if (submode == ExchangeSubMode) - return QLatin1String("cx"); - if (submode == ReplaceWithRegisterSubMode) - return QLatin1String("gr"); - if (submode == InvertCaseSubMode) - return QLatin1String("g~"); - if (submode == DownCaseSubMode) - return QLatin1String("gu"); - if (submode == UpCaseSubMode) - return QLatin1String("gU"); - if (submode == IndentSubMode) - return QLatin1String("="); - if (submode == ShiftRightSubMode) - return QLatin1String(">"); - if (submode == ShiftLeftSubMode) - return QLatin1String("<"); +QString dotCommandFromSubMode(SubMode submode) { + if (submode == ChangeSubMode) return QLatin1String("c"); + if (submode == DeleteSubMode) return QLatin1String("d"); + if (submode == CommentSubMode) return QLatin1String("gc"); + if (submode == DeleteSurroundingSubMode) return QLatin1String("ds"); + if (submode == ChangeSurroundingSubMode) return QLatin1String("c"); + if (submode == AddSurroundingSubMode) return QLatin1String("y"); + if (submode == ExchangeSubMode) return QLatin1String("cx"); + if (submode == ReplaceWithRegisterSubMode) return QLatin1String("gr"); + if (submode == InvertCaseSubMode) return QLatin1String("g~"); + if (submode == DownCaseSubMode) return QLatin1String("gu"); + if (submode == UpCaseSubMode) return QLatin1String("gU"); + if (submode == IndentSubMode) return QLatin1String("="); + if (submode == ShiftRightSubMode) return QLatin1String(">"); + if (submode == ShiftLeftSubMode) return QLatin1String("<"); return QString(); } QDebug operator<<(QDebug ts, const Input &input) { return input.dump(ts); } -class Inputs : public QVector -{ -public: +class Inputs : public QVector { + public: Inputs() = default; explicit Inputs(const QString &str, bool noremap = true, bool silent = false) - : m_noremap(noremap), m_silent(silent) - { + : m_noremap(noremap), m_silent(silent) { parseFrom(str); squeeze(); } @@ -1481,23 +1299,20 @@ public: bool silent() const { return m_silent; } -private: + private: void parseFrom(const QString &str); bool m_noremap = true; bool m_silent = false; }; -static Input parseVimKeyName(const QString &keyName) -{ - if (keyName.length() == 1) - return Input(keyName.at(0)); +static Input parseVimKeyName(const QString &keyName) { + if (keyName.length() == 1) return Input(keyName.at(0)); const QStringList keys = keyName.split('-'); const int len = keys.length(); - if (len == 1 && keys.at(0).toUpper() == "NOP") - return Nop; + if (len == 1 && keys.at(0).toUpper() == "NOP") return Nop; Qt::KeyboardModifiers mods = NoModifier; for (int i = 0; i < len - 1; ++i) { @@ -1520,15 +1335,13 @@ static Input parseVimKeyName(const QString &keyName) // find key name QMap::ConstIterator it = vimKeyNames().constFind(key.toUpper()); - if (it != vimKeyNames().end()) - return Input(*it, mods); + if (it != vimKeyNames().end()) return Input(*it, mods); } return Input(); } -void Inputs::parseFrom(const QString &str) -{ +void Inputs::parseFrom(const QString &str) { const int n = str.size(); for (int i = 0; i < n; ++i) { const QChar c = str.at(i); @@ -1536,9 +1349,8 @@ void Inputs::parseFrom(const QString &str) int j = str.indexOf('>', i); Input input; if (j != -1) { - const QString key = str.mid(i+1, j - i - 1); - if (!key.contains('<')) - input = parseVimKeyName(key); + const QString key = str.mid(i + 1, j - i - 1); + if (!key.contains('<')) input = parseVimKeyName(key); } if (input.isValid()) { append(input); @@ -1552,9 +1364,8 @@ void Inputs::parseFrom(const QString &str) } } -class History -{ -public: +class History { + public: History() : m_items(QString()) {} void append(const QString &item); const QString &move(const QString &prefix, int skip); @@ -1562,50 +1373,46 @@ public: const QStringList &items() const { return m_items; } void restart() { m_index = m_items.size() - 1; } -private: + private: // Last item is always empty or current search prefix. QStringList m_items; int m_index = 0; }; -void History::append(const QString &item) -{ - if (item.isEmpty()) - return; +void History::append(const QString &item) { + if (item.isEmpty()) return; m_items.pop_back(); m_items.removeAll(item); m_items << item << QString(); restart(); } -const QString &History::move(const QString &prefix, int skip) -{ - if (!current().startsWith(prefix)) - restart(); +const QString &History::move(const QString &prefix, int skip) { + if (!current().startsWith(prefix)) restart(); - if (m_items.last() != prefix) - m_items[m_items.size() - 1] = prefix; + if (m_items.last() != prefix) m_items[m_items.size() - 1] = prefix; int i = m_index + skip; if (!prefix.isEmpty()) - for (; i >= 0 && i < m_items.size() && !m_items[i].startsWith(prefix); i += skip) - ; - if (i >= 0 && i < m_items.size()) - m_index = i; + for (; i >= 0 && i < m_items.size() && !m_items[i].startsWith(prefix); i += skip); + if (i >= 0 && i < m_items.size()) m_index = i; return current(); } // Command line buffer with prompt (i.e. :, / or ? characters), text contents and cursor position. -class CommandBuffer -{ -public: +class CommandBuffer { + public: void setPrompt(const QChar &prompt) { m_prompt = prompt; } - void setContents(const QString &s) { m_buffer = s; m_anchor = m_pos = s.size(); } + void setContents(const QString &s) { + m_buffer = s; + m_anchor = m_pos = s.size(); + } - void setContents(const QString &s, int pos, int anchor = -1) - { - m_buffer = s; m_pos = m_userPos = pos; m_anchor = anchor >= 0 ? anchor : pos; + void setContents(const QString &s, int pos, int anchor = -1) { + m_buffer = s; + m_pos = m_userPos = pos; + m_anchor = anchor >= 0 ? anchor : pos; } QString userContents() const { return m_buffer.left(m_userPos); } @@ -1616,38 +1423,48 @@ public: int anchorPos() const { return m_anchor; } bool hasSelection() const { return m_pos != m_anchor; } - void insertChar(QChar c) { m_buffer.insert(m_pos++, c); m_anchor = m_userPos = m_pos; } - void insertText(const QString &s) - { - m_buffer.insert(m_pos, s); m_anchor = m_userPos = m_pos = m_pos + s.size(); + void insertChar(QChar c) { + m_buffer.insert(m_pos++, c); + m_anchor = m_userPos = m_pos; + } + void insertText(const QString &s) { + m_buffer.insert(m_pos, s); + m_anchor = m_userPos = m_pos = m_pos + s.size(); + } + void deleteChar() { + if (m_pos) m_buffer.remove(--m_pos, 1); + m_anchor = m_userPos = m_pos; } - void deleteChar() { if (m_pos) m_buffer.remove(--m_pos, 1); m_anchor = m_userPos = m_pos; } - void moveLeft() { if (m_pos) m_userPos = --m_pos; } - void moveRight() { if (m_pos < m_buffer.size()) m_userPos = ++m_pos; } + void moveLeft() { + if (m_pos) m_userPos = --m_pos; + } + void moveRight() { + if (m_pos < m_buffer.size()) m_userPos = ++m_pos; + } void moveStart() { m_userPos = m_pos = 0; } void moveEnd() { m_userPos = m_pos = m_buffer.size(); } void setHistoryAutoSave(bool autoSave) { m_historyAutoSave = autoSave; } bool userContentsValid() const { return m_userPos >= 0 && m_userPos <= m_buffer.size(); } - void historyDown() { if (userContentsValid()) setContents(m_history.move(userContents(), 1)); } - void historyUp() { if (userContentsValid()) setContents(m_history.move(userContents(), -1)); } + void historyDown() { + if (userContentsValid()) setContents(m_history.move(userContents(), 1)); + } + void historyUp() { + if (userContentsValid()) setContents(m_history.move(userContents(), -1)); + } const QStringList &historyItems() const { return m_history.items(); } - void historyPush(const QString &item = QString()) - { + void historyPush(const QString &item = QString()) { m_history.append(item.isNull() ? contents() : item); } - void clear() - { - if (m_historyAutoSave) - historyPush(); + void clear() { + if (m_historyAutoSave) historyPush(); m_buffer.clear(); m_anchor = m_userPos = m_pos = 0; } - QString display() const - { + QString display() const { QString msg(m_prompt); for (int i = 0; i != m_buffer.size(); ++i) { const QChar c = m_buffer.at(i); @@ -1661,8 +1478,7 @@ public: return msg; } - void deleteSelected() - { + void deleteSelected() { if (m_pos < m_anchor) { m_buffer.remove(m_pos, m_anchor - m_pos); m_anchor = m_pos; @@ -1672,8 +1488,7 @@ public: } } - bool handleInput(const Input &input) - { + bool handleInput(const Input &input) { if (input.isShift(Key_Left)) { moveLeft(); } else if (input.isShift(Key_Right)) { @@ -1708,8 +1523,7 @@ public: deleteChar(); } } else if (!input.text().isEmpty()) { - if (hasSelection()) - deleteSelected(); + if (hasSelection()) deleteSelected(); insertText(input.text()); } else { return false; @@ -1717,23 +1531,23 @@ public: return true; } -private: + private: QString m_buffer; QChar m_prompt; History m_history; int m_pos = 0; int m_anchor = 0; - int m_userPos = 0; // last position of inserted text (for retrieving history items) - bool m_historyAutoSave = true; // store items to history on clear()? + int m_userPos = 0; // last position of inserted text (for retrieving history items) + bool m_historyAutoSave = true; // store items to history on clear()? }; // Mappings for a specific mode (trie structure) -class ModeMapping : public QMap -{ -public: +class ModeMapping : public QMap { + public: const Inputs &value() const { return m_value; } void setValue(const Inputs &value) { m_value = value; } -private: + + private: Inputs m_value; }; @@ -1741,26 +1555,22 @@ private: using Mappings = QHash; // Iterator for mappings -class MappingsIterator : public QVector -{ -public: +class MappingsIterator : public QVector { + public: MappingsIterator(Mappings *mappings, char mode = -1, const Inputs &inputs = Inputs()) - : m_parent(mappings) - { + : m_parent(mappings) { reset(mode); walk(inputs); } // Reset iterator state. Keep previous mode if 0. - void reset(char mode = 0) - { + void reset(char mode = 0) { clear(); m_lastValid = -1; m_currentInputs.clear(); if (mode != 0) { m_mode = mode; - if (mode != -1) - m_modeMapping = m_parent->find(mode); + if (mode != -1) m_modeMapping = m_parent->find(mode); } } @@ -1775,48 +1585,37 @@ public: // Return size of current map. int mapLength() const { return m_lastValid + 1; } - bool walk(const Input &input) - { + bool walk(const Input &input) { m_currentInputs.append(input); - if (m_modeMapping == m_parent->end()) - return false; + if (m_modeMapping == m_parent->end()) return false; ModeMapping::Iterator it; if (isValid()) { it = last()->find(input); - if (it == last()->end()) - return false; + if (it == last()->end()) return false; } else { it = m_modeMapping->find(input); - if (it == m_modeMapping->end()) - return false; + if (it == m_modeMapping->end()) return false; } - if (!it->value().isEmpty()) - m_lastValid = size(); + if (!it->value().isEmpty()) m_lastValid = size(); append(it); return true; } - bool walk(const Inputs &inputs) - { + bool walk(const Inputs &inputs) { for (const Input &input : inputs) { - if (!walk(input)) - return false; + if (!walk(input)) return false; } return true; } // Return current mapped value. Iterator must be valid. - const Inputs &inputs() const - { - return at(m_lastValid)->value(); - } + const Inputs &inputs() const { return at(m_lastValid)->value(); } - void remove() - { + void remove() { if (isValid()) { if (canExtend()) { last()->setValue(Inputs()); @@ -1825,11 +1624,9 @@ public: while (last()->empty()) { at(size() - 2)->erase(last()); pop_back(); - if (size() == 1 || !last()->value().isEmpty()) - break; + if (size() == 1 || !last()->value().isEmpty()) break; } - if (last()->empty() && last()->value().isEmpty()) - m_modeMapping->erase(last()); + if (last()->empty() && last()->value().isEmpty()) m_modeMapping->erase(last()); } else if (last()->empty() && !last()->value().isEmpty()) { m_modeMapping->erase(last()); } @@ -1837,18 +1634,15 @@ public: } } - void setInputs(const Inputs &key, const Inputs &inputs, bool unique = false) - { + void setInputs(const Inputs &key, const Inputs &inputs, bool unique = false) { ModeMapping *current = &(*m_parent)[m_mode]; - for (const Input &input : key) - current = &(*current)[input]; - if (!unique || current->value().isEmpty()) - current->setValue(inputs); + for (const Input &input : key) current = &(*current)[input]; + if (!unique || current->value().isEmpty()) current->setValue(inputs); } const Inputs ¤tInputs() const { return m_currentInputs; } -private: + private: Mappings *m_parent; Mappings::Iterator m_modeMapping; int m_lastValid = -1; @@ -1866,9 +1660,8 @@ struct MappingState { bool editBlock = false; }; -class FakeVimHandler::Private : public QObject -{ -public: +class FakeVimHandler::Private : public QObject { + public: Private(FakeVimHandler *parent, QWidget *widget); EventResult handleEvent(QKeyEvent *ev); @@ -1877,7 +1670,7 @@ public: bool parseLineRange(QString *line, ExCommand *cmd); int parseLineAddress(QString *cmd); void parseRangeCount(const QString &line, Range *range) const; - void handleCommand(const QString &cmd); // Sets m_tc + handleExCommand + void handleCommand(const QString &cmd); // Sets m_tc + handleExCommand void handleExCommand(const QString &cmd); void installEventFilter(); @@ -1905,10 +1698,10 @@ public: EventResult handleDefaultKey(const Input &input); bool handleCommandBufferPaste(const Input &input); EventResult handleCurrentMapAsDefault(); - void prependInputs(const QVector &inputs); // Handle inputs. - void prependMapping(const Inputs &inputs); // Handle inputs as mapping. - bool expandCompleteMapping(); // Return false if current mapping is not complete. - bool extendMapping(const Input &input); // Return false if no suitable mappig found. + void prependInputs(const QVector &inputs); // Handle inputs. + void prependMapping(const Inputs &inputs); // Handle inputs as mapping. + bool expandCompleteMapping(); // Return false if current mapping is not complete. + bool extendMapping(const Input &input); // Return false if no suitable mappig found. void endMapping(); bool canHandleMapping(); void clearPendingInput(); @@ -1942,13 +1735,14 @@ public: bool handleMacroRecordSubMode(const Input &); bool handleMacroExecuteSubMode(const Input &); - bool handleCount(const Input &); // Handle count for commands (return false if input isn't count). + bool handleCount( + const Input &); // Handle count for commands (return false if input isn't count). bool handleMovement(const Input &); EventResult handleExMode(const Input &); EventResult handleSearchSubSubMode(const Input &); bool handleCommandSubSubMode(const Input &); - void fixSelection(); // Fix selection according to current range, move and command modes. + void fixSelection(); // Fix selection according to current range, move and command modes. bool finishSearch(); void finishMovement(const QString &dotCommandMovement = QString()); @@ -1969,7 +1763,8 @@ public: void updateFind(bool isComplete); void resetCount(); - bool isInputCount(const Input &) const; // Return true if input can be used as count for commands. + bool isInputCount( + const Input &) const; // Return true if input can be used as count for commands. int mvCount() const { return qMax(1, g.mvcount); } int opCount() const { return qMax(1, g.opcount); } int count() const { return mvCount() * opCount(); } @@ -1986,28 +1781,33 @@ public: bool atEmptyLine(const QTextCursor &tc) const; bool atEmptyLine() const; bool atBoundary(bool end, bool simple, bool onlyWords = false, - const QTextCursor &tc = QTextCursor()) const; + const QTextCursor &tc = QTextCursor()) const; bool atWordBoundary(bool end, bool simple, const QTextCursor &tc = QTextCursor()) const; bool atWordStart(bool simple, const QTextCursor &tc = QTextCursor()) const; bool atWordEnd(bool simple, const QTextCursor &tc = QTextCursor()) const; bool isFirstNonBlankOnLine(int pos); - int lastPositionInDocument(bool ignoreMode = false) const; // Returns last valid position in doc. - int firstPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos - int lastPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos - int lineForPosition(int pos) const; // 1 based line, 0 based pos - QString lineContents(int line) const; // 1 based line + int lastPositionInDocument( + bool ignoreMode = false) const; // Returns last valid position in doc. + int firstPositionInLine(int line, + bool onlyVisibleLines = true) const; // 1 based line, 0 based pos + int lastPositionInLine(int line, + bool onlyVisibleLines = true) const; // 1 based line, 0 based pos + int lineForPosition(int pos) const; // 1 based line, 0 based pos + QString lineContents(int line) const; // 1 based line QString textAt(int from, int to) const; - void setLineContents(int line, const QString &contents); // 1 based line - int blockBoundary(const QString &left, const QString &right, - bool end, int count) const; // end or start position of current code block + void setLineContents(int line, const QString &contents); // 1 based line + int blockBoundary(const QString &left, const QString &right, bool end, + int count) const; // end or start position of current code block int lineNumber(const QTextBlock &block) const; int columnAt(int pos) const; int blockNumberAt(int pos) const; QTextBlock blockAt(int pos) const; - QTextBlock nextLine(const QTextBlock &block) const; // following line (respects wrapped parts) - QTextBlock previousLine(const QTextBlock &block) const; // previous line (respects wrapped parts) + QTextBlock nextLine( + const QTextBlock &block) const; // following line (respects wrapped parts) + QTextBlock previousLine( + const QTextBlock &block) const; // previous line (respects wrapped parts) int linesOnScreen() const; int linesInDocument() const; @@ -2015,24 +1815,24 @@ public: // The following use all zero-based counting. int cursorLineOnScreen() const; int cursorLine() const; - int cursorBlockNumber() const; // "." address - int physicalCursorColumn() const; // as stored in the data - int logicalCursorColumn() const; // as visible on screen + int cursorBlockNumber() const; // "." address + int physicalCursorColumn() const; // as stored in the data + int logicalCursorColumn() const; // as visible on screen int physicalToLogicalColumn(int physical, const QString &text) const; int logicalToPhysicalColumn(int logical, const QString &text) const; - int windowScrollOffset() const; // return scrolloffset but max half the current window height - Column cursorColumn() const; // as visible on screen + int windowScrollOffset() const; // return scrolloffset but max half the current window height + Column cursorColumn() const; // as visible on screen void updateFirstVisibleLine(); int firstVisibleLine() const; int lastVisibleLine() const; - int lineOnTop(int count = 1) const; // [count]-th line from top reachable without scrolling - int lineOnBottom(int count = 1) const; // [count]-th line from bottom reachable without scrolling + int lineOnTop(int count = 1) const; // [count]-th line from top reachable without scrolling + int lineOnBottom( + int count = 1) const; // [count]-th line from bottom reachable without scrolling void scrollToLine(int line); void scrollUp(int count); void scrollDown(int count) { scrollUp(-count); } void updateScrollOffset(); - void alignViewportToCursor(Qt::AlignmentFlag align, int line = -1, - bool moveToNonBlank = false); + void alignViewportToCursor(Qt::AlignmentFlag align, int line = -1, bool moveToNonBlank = false); int lineToBlockNumber(int line) const; @@ -2088,8 +1888,7 @@ public: void movePageDown(int count = 1); void movePageUp(int count = 1) { movePageDown(-count); } void dump(const char *msg) const { - qDebug() << msg << "POS: " << anchor() << position() - << "VISUAL: " << g.visualMode; + qDebug() << msg << "POS: " << anchor() << position() << "VISUAL: " << g.visualMode; } void moveRight(int n = 1) { if (isVisualCharMode()) { @@ -2100,8 +1899,7 @@ public: } else { m_cursor.movePosition(Right, KeepAnchor, n); } - if (atEndOfLine()) - q->fold(1, false); + if (atEndOfLine()) q->fold(1, false); setTargetColumn(); } void moveLeft(int n = 1) { @@ -2110,23 +1908,15 @@ public: } void moveToNextCharacter() { moveRight(); - if (atEndOfLine()) - moveRight(); + if (atEndOfLine()) moveRight(); } void moveToPreviousCharacter() { moveLeft(); - if (atBlockStart()) - moveLeft(); - } - void setAnchor() { - m_cursor.setPosition(position(), MoveAnchor); - } - void setAnchor(int position) { - m_cursor.setPosition(position, KeepAnchor); - } - void setPosition(int position) { - m_cursor.setPosition(position, KeepAnchor); + if (atBlockStart()) moveLeft(); } + void setAnchor() { m_cursor.setPosition(position(), MoveAnchor); } + void setAnchor(int position) { m_cursor.setPosition(position, KeepAnchor); } + void setPosition(int position) { m_cursor.setPosition(position, KeepAnchor); } void setAnchorAndPosition(int anchor, int position) { m_cursor.setPosition(anchor, MoveAnchor); m_cursor.setPosition(position, KeepAnchor); @@ -2192,20 +1982,14 @@ public: bool isInsertMode() const { return g.mode == InsertMode || g.mode == ReplaceMode; } // Waiting for movement operator. bool isOperatorPending() const { - return g.submode == ChangeSubMode - || g.submode == DeleteSubMode - || g.submode == ExchangeSubMode - || g.submode == CommentSubMode - || g.submode == ReplaceWithRegisterSubMode - || g.submode == AddSurroundingSubMode - || g.submode == FilterSubMode - || g.submode == IndentSubMode - || g.submode == ShiftLeftSubMode - || g.submode == ShiftRightSubMode - || g.submode == InvertCaseSubMode - || g.submode == DownCaseSubMode - || g.submode == UpCaseSubMode - || g.submode == YankSubMode; } + return g.submode == ChangeSubMode || g.submode == DeleteSubMode || + g.submode == ExchangeSubMode || g.submode == CommentSubMode || + g.submode == ReplaceWithRegisterSubMode || g.submode == AddSurroundingSubMode || + g.submode == FilterSubMode || g.submode == IndentSubMode || + g.submode == ShiftLeftSubMode || g.submode == ShiftRightSubMode || + g.submode == InvertCaseSubMode || g.submode == DownCaseSubMode || + g.submode == UpCaseSubMode || g.submode == YankSubMode; + } bool isVisualMode() const { return g.visualMode != NoVisualMode; } bool isNoVisualMode() const { return g.visualMode == NoVisualMode; } @@ -2242,19 +2026,19 @@ public: // Handle current command as synonym void handleAs(const QString &command); -public: + public: QTextEdit *m_textedit; QPlainTextEdit *m_plaintextedit; - bool m_wasReadOnly; // saves read-only state of document + bool m_wasReadOnly; // saves read-only state of document - bool m_inFakeVim; // true if currently processing a key press or a command + bool m_inFakeVim; // true if currently processing a key press or a command FakeVimHandler *q; int m_register; BlockInsertMode m_visualBlockInsert; bool m_anchorPastEnd; - bool m_positionPastEnd; // '$' & 'l' in visual mode can move past eol + bool m_positionPastEnd; // '$' & 'l' in visual mode can move past eol QString m_currentFileName; @@ -2265,7 +2049,8 @@ public: // Transform text selected by cursor in current visual mode. using Transformation = std::function; - void transformText(const Range &range, QTextCursor &tc, const std::function &transform) const; + void transformText(const Range &range, QTextCursor &tc, + const std::function &transform) const; void transformText(const Range &range, const Transformation &transform); void insertText(QTextCursor &tc, const QString &text); @@ -2303,7 +2088,9 @@ public: void insertNewLine(); bool handleInsertInEditor(const Input &input); - bool passEventToEditor(QEvent &event, QTextCursor &tc); // Pass event to editor widget without filtering. Returns true if event was processed. + bool passEventToEditor(QEvent &event, + QTextCursor &tc); // Pass event to editor widget without filtering. + // Returns true if event was processed. // undo handling int revision() const { return document()->availableUndoSteps(); } @@ -2333,9 +2120,9 @@ public: CursorPosition markLessPosition() const { return mark('<').position(document()); } CursorPosition markGreaterPosition() const { return mark('>').position(document()); } - int m_targetColumn; // -1 if past end of line - int m_visualTargetColumn; // 'l' can move past eol in visual mode only - int m_targetColumnWrapped; // column in current part of wrapped line + int m_targetColumn; // -1 if past end of line + int m_visualTargetColumn; // 'l' can move past eol in visual mode only + int m_targetColumnWrapped; // column in current part of wrapped line // auto-indent QString tabExpand(int len) const; @@ -2348,7 +2135,8 @@ public: QString registerContents(int reg) const; void setRegister(int reg, const QString &contents, RangeMode mode); RangeMode registerRangeMode(int reg) const; - void getRegisterType(int *reg, bool *isClipboard, bool *isSelection, bool *append = nullptr) const; + void getRegisterType(int *reg, bool *isClipboard, bool *isSelection, + bool *append = nullptr) const; void recordJump(int position = -1); void jump(int distance); @@ -2357,10 +2145,10 @@ public: QTextCursor m_searchCursor; int m_searchStartPosition; int m_searchFromScreenLine; - QString m_highlighted; // currently highlighted text + QString m_highlighted; // currently highlighted text - bool handleExCommandHelper(ExCommand &cmd); // Returns success. - bool handleExPluginCommand(const ExCommand &cmd); // Handled by plugin? + bool handleExCommandHelper(ExCommand &cmd); // Returns success. + bool handleExPluginCommand(const ExCommand &cmd); // Handled by plugin? bool handleExBangCommand(const ExCommand &cmd); bool handleExYankDeleteCommand(const ExCommand &cmd); bool handleExChangeCommand(const ExCommand &cmd); @@ -2399,15 +2187,14 @@ public: void miniBufferTextEdited(const QString &text, int cursorPos, int anchorPos); // Data shared among editors with same document. - struct BufferData - { + struct BufferData { QStack undo; QStack redo; State undoState; int lastRevision = 0; - int editBlockLevel = 0; // current level of edit blocks - bool breakEditBlock = false; // if true, joinPreviousEditBlock() starts new edit block + int editBlockLevel = 0; // current level of edit blocks + bool breakEditBlock = false; // if true, joinPreviousEditBlock() starts new edit block QStack jumpListUndo; QStack jumpListRedo; @@ -2442,17 +2229,11 @@ public: BufferDataPtr m_buffer; // Data shared among all editors. - static struct GlobalData - { - GlobalData() - : mappings() - , currentMap(&mappings) - { - commandBuffer.setPrompt(':'); - } + static struct GlobalData { + GlobalData() : mappings(), currentMap(&mappings) { commandBuffer.setPrompt(':'); } // Current state. - bool passing = false; // let the core see the next event + bool passing = false; // let the core see the next event Mode mode = CommandMode; SubMode submode = NoSubMode; SubSubMode subsubmode = NoSubSubMode; @@ -2466,10 +2247,10 @@ public: MoveType movetype = MoveInclusive; RangeMode rangemode = RangeCharMode; - bool gflag = false; // whether current command started with 'g' + bool gflag = false; // whether current command started with 'g' // Extra data for ';'. - Input semicolonType; // 'f', 'F', 't', 'T' + Input semicolonType; // 'f', 'F', 't', 'T' QString semicolonKey; // Repetition. @@ -2496,11 +2277,12 @@ public: QString currentCommand; // Search state. - QString lastSearch; // last search expression as entered by user - QString lastNeedle; // last search expression translated with vimPatternToQtPattern() - bool lastSearchForward = false; // last search command was '/' or '*' - bool highlightsCleared = false; // ':nohlsearch' command is active until next search - bool findPending = false; // currently searching using external tool (until editor is focused again) + QString lastSearch; // last search expression as entered by user + QString lastNeedle; // last search expression translated with vimPatternToQtPattern() + bool lastSearchForward = false; // last search command was '/' or '*' + bool highlightsCleared = false; // ':nohlsearch' command is active until next search + bool findPending = + false; // currently searching using external tool (until editor is focused again) // Last substitution command. QString lastSubstituteFlags; @@ -2523,18 +2305,15 @@ public: // If non-empty, cx{motion} replaces the {motion} with selectText(*exchangeData) Utils::optional exchangeRange; - bool surroundUpperCaseS; // True for yS and cS, false otherwise - QString surroundFunction; // Used for storing the function name provided to ys{motion}f + bool surroundUpperCaseS; // True for yS and cS, false otherwise + QString surroundFunction; // Used for storing the function name provided to ys{motion}f } g; FakeVimSettings &s = *fakeVimSettings(); }; -static void initSingleShotTimer(QTimer *timer, - int interval, - FakeVimHandler::Private *receiver, - void (FakeVimHandler::Private::*slot)()) -{ +static void initSingleShotTimer(QTimer *timer, int interval, FakeVimHandler::Private *receiver, + void (FakeVimHandler::Private::*slot)()) { timer->setSingleShot(true); timer->setInterval(interval); QObject::connect(timer, &QTimer::timeout, receiver, slot); @@ -2542,8 +2321,7 @@ static void initSingleShotTimer(QTimer *timer, FakeVimHandler::Private::GlobalData FakeVimHandler::Private::g; -FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget) -{ +FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget) { q = parent; m_textedit = qobject_cast(widget); m_plaintextedit = qobject_cast(widget); @@ -2551,16 +2329,15 @@ FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget) init(); if (editor()) { - connect(EDITOR(document()), &QTextDocument::contentsChange, - this, &Private::onContentsChanged); - connect(EDITOR(document()), &QTextDocument::undoCommandAdded, - this, &Private::onUndoCommandAdded); + connect(EDITOR(document()), &QTextDocument::contentsChange, this, + &Private::onContentsChanged); + connect(EDITOR(document()), &QTextDocument::undoCommandAdded, this, + &Private::onUndoCommandAdded); m_buffer->lastRevision = revision(); } } -void FakeVimHandler::Private::init() -{ +void FakeVimHandler::Private::init() { m_cursor = QTextCursor(document()); m_cursorNeedsUpdate = true; m_inFakeVim = false; @@ -2586,8 +2363,7 @@ void FakeVimHandler::Private::init() setupCharClass(); } -void FakeVimHandler::Private::focus() -{ +void FakeVimHandler::Private::focus() { m_buffer->currentHandler = this; enterFakeVim(); @@ -2614,13 +2390,9 @@ void FakeVimHandler::Private::focus() leaveFakeVim(false); } -void FakeVimHandler::Private::unfocus() -{ - fixExternalCursor(false); -} +void FakeVimHandler::Private::unfocus() { fixExternalCursor(false); } -void FakeVimHandler::Private::fixExternalCursor(bool focus) -{ +void FakeVimHandler::Private::fixExternalCursor(bool focus) { m_fixCursorTimer.stop(); if (isVisualCharMode() && !focus && !hasThinCursor()) { @@ -2635,8 +2407,7 @@ void FakeVimHandler::Private::fixExternalCursor(bool focus) } } -void FakeVimHandler::Private::fixExternalCursorPosition(bool focus) -{ +void FakeVimHandler::Private::fixExternalCursorPosition(bool focus) { QTextCursor tc = editorCursor(); if (tc.anchor() < tc.position()) { tc.movePosition(focus ? Left : Right, KeepAnchor); @@ -2646,15 +2417,13 @@ void FakeVimHandler::Private::fixExternalCursorPosition(bool focus) setThinCursor(!focus); } -void FakeVimHandler::Private::enterFakeVim() -{ +void FakeVimHandler::Private::enterFakeVim() { if (m_inFakeVim) { qWarning("enterFakeVim() shouldn't be called recursively!"); return; } - if (!m_buffer->currentHandler) - m_buffer->currentHandler = this; + if (!m_buffer->currentHandler) m_buffer->currentHandler = this; pullOrCreateBufferData(); @@ -2667,8 +2436,7 @@ void FakeVimHandler::Private::enterFakeVim() updateFirstVisibleLine(); } -void FakeVimHandler::Private::leaveFakeVim(bool needUpdate) -{ +void FakeVimHandler::Private::leaveFakeVim(bool needUpdate) { if (!m_inFakeVim) { qWarning("enterFakeVim() not called before leaveFakeVim()!"); return; @@ -2676,8 +2444,7 @@ void FakeVimHandler::Private::leaveFakeVim(bool needUpdate) // The command might have destroyed the editor. if (m_textedit || m_plaintextedit) { - if (s.showMarks.value()) - updateSelection(); + if (s.showMarks.value()) updateSelection(); updateMiniBuffer(); @@ -2699,40 +2466,33 @@ void FakeVimHandler::Private::leaveFakeVim(bool needUpdate) m_inFakeVim = false; } -void FakeVimHandler::Private::leaveFakeVim(EventResult eventResult) -{ +void FakeVimHandler::Private::leaveFakeVim(EventResult eventResult) { leaveFakeVim(eventResult == EventHandled || eventResult == EventCancelled); } -bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev) -{ +bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev) { const int key = ev->key(); const Qt::KeyboardModifiers mods = ev->modifiers(); KEY_DEBUG("SHORTCUT OVERRIDE" << key << " PASSING: " << g.passing); if (key == Key_Escape) { - if (g.subsubmode == SearchSubSubMode) - return true; + if (g.subsubmode == SearchSubSubMode) return true; // Not sure this feels good. People often hit Esc several times. - if (isNoVisualMode() - && g.mode == CommandMode - && g.submode == NoSubMode - && g.currentCommand.isEmpty() - && g.returnToMode == CommandMode) + if (isNoVisualMode() && g.mode == CommandMode && g.submode == NoSubMode && + g.currentCommand.isEmpty() && g.returnToMode == CommandMode) return false; return true; } // We are interested in overriding most Ctrl key combinations. - if (isOnlyControlModifier(mods) - && !s.passControlKey.value() - && ((key >= Key_A && key <= Key_Z && key != Key_K) - || key == Key_BracketLeft || key == Key_BracketRight)) { + if (isOnlyControlModifier(mods) && !s.passControlKey.value() && + ((key >= Key_A && key <= Key_Z && key != Key_K) || key == Key_BracketLeft || + key == Key_BracketRight)) { // Ctrl-K is special as it is the Core's default notion of Locator if (g.passing) { KEY_DEBUG(" PASSING CTRL KEY"); // We get called twice on the same key - //g.passing = false; + // g.passing = false; return false; } KEY_DEBUG(" NOT PASSING CTRL KEY"); @@ -2743,14 +2503,12 @@ bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev) return false; } -EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev) -{ +EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev) { const int key = ev->key(); const Qt::KeyboardModifiers mods = ev->modifiers(); - if (key == Key_Shift || key == Key_Alt || key == Key_Control - || key == Key_AltGr || key == Key_Meta) - { + if (key == Key_Shift || key == Key_Alt || key == Key_Control || key == Key_AltGr || + key == Key_Meta) { KEY_DEBUG("PLAIN MODIFIER"); return EventUnhandled; } @@ -2758,48 +2516,45 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev) if (g.passing) { passShortcuts(false); KEY_DEBUG("PASSING PLAIN KEY..." << ev->key() << ev->text()); - //if (input.is(',')) { // use ',,' to leave, too. - // qDebug() << "FINISHED..."; - // return EventHandled; - //} + // if (input.is(',')) { // use ',,' to leave, too. + // qDebug() << "FINISHED..."; + // return EventHandled; + // } KEY_DEBUG(" PASS TO CORE"); return EventPassedToCore; } #ifndef FAKEVIM_STANDALONE bool inSnippetMode = false; - QMetaObject::invokeMethod(editor(), - "inSnippetMode", Q_ARG(bool *, &inSnippetMode)); + QMetaObject::invokeMethod(editor(), "inSnippetMode", Q_ARG(bool *, &inSnippetMode)); - if (inSnippetMode) - return EventPassedToCore; + if (inSnippetMode) return EventPassedToCore; #endif // Fake "End of line" - //m_tc = m_cursor; + // m_tc = m_cursor; - //bool hasBlock = false; - //q->requestHasBlockSelection(&hasBlock); - //qDebug() << "IMPORT BLOCK 2:" << hasBlock; + // bool hasBlock = false; + // q->requestHasBlockSelection(&hasBlock); + // qDebug() << "IMPORT BLOCK 2:" << hasBlock; - //if (0 && hasBlock) { - // (pos > anc) ? --pos : --anc; + // if (0 && hasBlock) { + // (pos > anc) ? --pos : --anc; - //if ((mods & RealControlModifier) != 0) { - // if (key >= Key_A && key <= Key_Z) - // key = shift(key); // make it lower case - // key = control(key); - //} else if (key >= Key_A && key <= Key_Z && (mods & Qt::ShiftModifier) == 0) { - // key = shift(key); - //} + // if ((mods & RealControlModifier) != 0) { + // if (key >= Key_A && key <= Key_Z) + // key = shift(key); // make it lower case + // key = control(key); + // } else if (key >= Key_A && key <= Key_Z && (mods & Qt::ShiftModifier) == 0) { + // key = shift(key); + // } - //QTC_ASSERT(g.mode == InsertMode || g.mode == ReplaceMode - // || !atBlockEnd() || block().length() <= 1, - // qDebug() << "Cursor at EOL before key handler"); + // QTC_ASSERT(g.mode == InsertMode || g.mode == ReplaceMode + // || !atBlockEnd() || block().length() <= 1, + // qDebug() << "Cursor at EOL before key handler"); const Input input(key, mods, ev->text()); - if (!input.isValid()) - return EventUnhandled; + if (!input.isValid()) return EventUnhandled; enterFakeVim(); EventResult result = handleKey(input); @@ -2807,25 +2562,18 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev) return result; } -void FakeVimHandler::Private::installEventFilter() -{ - EDITOR(installEventFilter(q)); -} +void FakeVimHandler::Private::installEventFilter() { EDITOR(installEventFilter(q)); } -void FakeVimHandler::Private::removeEventFilter() -{ - EDITOR(removeEventFilter(q)); -} +void FakeVimHandler::Private::removeEventFilter() { EDITOR(removeEventFilter(q)); } -void FakeVimHandler::Private::setupWidget() -{ +void FakeVimHandler::Private::setupWidget() { m_cursorNeedsUpdate = true; if (m_textedit) { - connect(m_textedit, &QTextEdit::cursorPositionChanged, - this, &FakeVimHandler::Private::onCursorPositionChanged, Qt::UniqueConnection); + connect(m_textedit, &QTextEdit::cursorPositionChanged, this, + &FakeVimHandler::Private::onCursorPositionChanged, Qt::UniqueConnection); } else { - connect(m_plaintextedit, &QPlainTextEdit::cursorPositionChanged, - this, &FakeVimHandler::Private::onCursorPositionChanged, Qt::UniqueConnection); + connect(m_plaintextedit, &QPlainTextEdit::cursorPositionChanged, this, + &FakeVimHandler::Private::onCursorPositionChanged, Qt::UniqueConnection); } enterFakeVim(); @@ -2838,10 +2586,8 @@ void FakeVimHandler::Private::setupWidget() leaveFakeVim(); } -void FakeVimHandler::Private::commitInsertState() -{ - if (!isInsertStateValid()) - return; +void FakeVimHandler::Private::commitInsertState() { + if (!isInsertStateValid()) return; QString &lastInsertion = m_buffer->lastInsertion; BufferData::InsertState &insertState = m_buffer->insertState; @@ -2872,8 +2618,7 @@ void FakeVimHandler::Private::commitInsertState() lastInsertion.replace(QRegularExpression("(^|\n)[\\t ]+"), "\\1"); } -void FakeVimHandler::Private::invalidateInsertState() -{ +void FakeVimHandler::Private::invalidateInsertState() { BufferData::InsertState &insertState = m_buffer->insertState; insertState.pos1 = -1; insertState.pos2 = position(); @@ -2886,20 +2631,17 @@ void FakeVimHandler::Private::invalidateInsertState() insertState.newLineAfter = false; } -bool FakeVimHandler::Private::isInsertStateValid() const -{ +bool FakeVimHandler::Private::isInsertStateValid() const { return m_buffer->insertState.pos1 != -1; } -void FakeVimHandler::Private::clearLastInsertion() -{ +void FakeVimHandler::Private::clearLastInsertion() { invalidateInsertState(); m_buffer->lastInsertion.clear(); m_buffer->insertState.pos1 = m_buffer->insertState.pos2; } -void FakeVimHandler::Private::ensureCursorVisible() -{ +void FakeVimHandler::Private::ensureCursorVisible() { int pos = position(); int anc = isVisualMode() ? anchor() : position(); @@ -2912,14 +2654,11 @@ void FakeVimHandler::Private::ensureCursorVisible() // FIXME: Moving cursor left/right or unfolding block immediately after block is folded // should restore cursor position inside block. // Changing cursor position after folding is not Vim behavior so at least record the jump. - if (block.isValid() && !block.isVisible()) - recordJump(); + if (block.isValid() && !block.isVisible()) recordJump(); pos = start; - while (block.isValid() && !block.isVisible()) - block = block.previous(); - if (block.isValid()) - pos = block.position() + qMin(m_targetColumn, block.length() - 2); + while (block.isValid() && !block.isVisible()) block = block.previous(); + if (block.isValid()) pos = block.position() + qMin(m_targetColumn, block.length() - 2); if (isVisualMode()) { anc = end; @@ -2933,14 +2672,12 @@ void FakeVimHandler::Private::ensureCursorVisible() } } -void FakeVimHandler::Private::updateEditor() -{ +void FakeVimHandler::Private::updateEditor() { setTabSize(s.tabStop.value()); setupCharClass(); } -void FakeVimHandler::Private::setTabSize(int tabSize) -{ +void FakeVimHandler::Private::setTabSize(int tabSize) { #if (QT_VERSION < QT_VERSION_CHECK(5, 11, 0)) const int charWidth = QFontMetrics(EDITOR(font())).width(' '); #else @@ -2956,10 +2693,9 @@ void FakeVimHandler::Private::setTabSize(int tabSize) #endif } -void FakeVimHandler::Private::restoreWidget(int tabSize) -{ - //EDITOR(removeEventFilter(q)); - //EDITOR(setReadOnly(m_wasReadOnly)); +void FakeVimHandler::Private::restoreWidget(int tabSize) { + // EDITOR(removeEventFilter(q)); + // EDITOR(setReadOnly(m_wasReadOnly)); setTabSize(tabSize); g.visualMode = NoVisualMode; // Force "ordinary" cursor. @@ -2967,16 +2703,15 @@ void FakeVimHandler::Private::restoreWidget(int tabSize) updateSelection(); updateHighlights(); if (m_textedit) { - disconnect(m_textedit, &QTextEdit::cursorPositionChanged, - this, &FakeVimHandler::Private::onCursorPositionChanged); + disconnect(m_textedit, &QTextEdit::cursorPositionChanged, this, + &FakeVimHandler::Private::onCursorPositionChanged); } else { - disconnect(m_plaintextedit, &QPlainTextEdit::cursorPositionChanged, - this, &FakeVimHandler::Private::onCursorPositionChanged); + disconnect(m_plaintextedit, &QPlainTextEdit::cursorPositionChanged, this, + &FakeVimHandler::Private::onCursorPositionChanged); } } -EventResult FakeVimHandler::Private::handleKey(const Input &input) -{ +EventResult FakeVimHandler::Private::handleKey(const Input &input) { KEY_DEBUG("HANDLE INPUT: " << input); bool hasInput = input.isValid(); @@ -3004,8 +2739,7 @@ EventResult FakeVimHandler::Private::handleKey(const Input &input) // Handle user mapping. if (canHandleMapping()) { if (extendMapping(in)) { - if (!hasInput || !g.currentMap.canExtend()) - expandCompleteMapping(); + if (!hasInput || !g.currentMap.canExtend()) expandCompleteMapping(); } else if (!expandCompleteMapping()) { r = handleCurrentMapAsDefault(); } @@ -3020,25 +2754,21 @@ EventResult FakeVimHandler::Private::handleKey(const Input &input) return EventHandled; } - if (r != EventHandled) - clearPendingInput(); + if (r != EventHandled) clearPendingInput(); return r; } -bool FakeVimHandler::Private::handleCommandBufferPaste(const Input &input) -{ - if (input.isControl('r') - && (g.subsubmode == SearchSubSubMode || g.mode == ExMode)) { +bool FakeVimHandler::Private::handleCommandBufferPaste(const Input &input) { + if (input.isControl('r') && (g.subsubmode == SearchSubSubMode || g.mode == ExMode)) { g.minibufferData = input; return true; } if (g.minibufferData.isControl('r')) { g.minibufferData = Input(); - if (input.isEscape()) - return true; - CommandBuffer &buffer = (g.subsubmode == SearchSubSubMode) - ? g.searchBuffer : g.commandBuffer; + if (input.isEscape()) return true; + CommandBuffer &buffer = + (g.subsubmode == SearchSubSubMode) ? g.searchBuffer : g.commandBuffer; if (input.isControl('w')) { QTextCursor tc = m_cursor; tc.select(QTextCursor::WordUnderCursor); @@ -3054,14 +2784,12 @@ bool FakeVimHandler::Private::handleCommandBufferPaste(const Input &input) return false; } -EventResult FakeVimHandler::Private::handleDefaultKey(const Input &input) -{ +EventResult FakeVimHandler::Private::handleDefaultKey(const Input &input) { if (g.passing) { passShortcuts(false); QKeyEvent event(QEvent::KeyPress, input.key(), input.modifiers(), input.text()); bool accepted = QApplication::sendEvent(editor()->window(), &event); - if (accepted || (!m_textedit && !m_plaintextedit)) - return EventHandled; + if (accepted || (!m_textedit && !m_plaintextedit)) return EventHandled; } if (input == Nop) @@ -3077,29 +2805,23 @@ EventResult FakeVimHandler::Private::handleDefaultKey(const Input &input) return EventUnhandled; } -EventResult FakeVimHandler::Private::handleCurrentMapAsDefault() -{ +EventResult FakeVimHandler::Private::handleCurrentMapAsDefault() { // If mapping has failed take the first input from it and try default command. const Inputs &inputs = g.currentMap.currentInputs(); - if (inputs.isEmpty()) - return EventHandled; + if (inputs.isEmpty()) return EventHandled; Input in = inputs.front(); - if (inputs.size() > 1) - prependInputs(inputs.mid(1)); + if (inputs.size() > 1) prependInputs(inputs.mid(1)); g.currentMap.reset(); return handleDefaultKey(in); } -void FakeVimHandler::Private::prependInputs(const QVector &inputs) -{ - for (int i = inputs.size() - 1; i >= 0; --i) - g.pendingInput.prepend(inputs[i]); +void FakeVimHandler::Private::prependInputs(const QVector &inputs) { + for (int i = inputs.size() - 1; i >= 0; --i) g.pendingInput.prepend(inputs[i]); } -void FakeVimHandler::Private::prependMapping(const Inputs &inputs) -{ +void FakeVimHandler::Private::prependMapping(const Inputs &inputs) { // FIXME: Implement Vim option maxmapdepth (default value is 1000). if (g.mapDepth >= 1000) { const int i = qMax(0, g.pendingInput.lastIndexOf(Input())); @@ -3117,15 +2839,12 @@ void FakeVimHandler::Private::prependMapping(const Inputs &inputs) // start new edit block (undo/redo) only if necessary bool editBlock = m_buffer->editBlockLevel == 0 && !(isInsertMode() && isInsertStateValid()); - if (editBlock) - beginLargeEditBlock(); + if (editBlock) beginLargeEditBlock(); g.mapStates << MappingState(inputs.noremap(), inputs.silent(), editBlock); } -bool FakeVimHandler::Private::expandCompleteMapping() -{ - if (!g.currentMap.isComplete()) - return false; +bool FakeVimHandler::Private::expandCompleteMapping() { + if (!g.currentMap.isComplete()) return false; const Inputs &inputs = g.currentMap.inputs(); int usedInputs = g.currentMap.mapLength(); @@ -3136,54 +2855,39 @@ bool FakeVimHandler::Private::expandCompleteMapping() return true; } -bool FakeVimHandler::Private::extendMapping(const Input &input) -{ - if (!g.currentMap.isValid()) - g.currentMap.reset(currentModeCode()); +bool FakeVimHandler::Private::extendMapping(const Input &input) { + if (!g.currentMap.isValid()) g.currentMap.reset(currentModeCode()); return g.currentMap.walk(input); } -void FakeVimHandler::Private::endMapping() -{ - if (!g.currentMap.canExtend()) - --g.mapDepth; - if (g.mapStates.isEmpty()) - return; - if (g.mapStates.last().editBlock) - endEditBlock(); +void FakeVimHandler::Private::endMapping() { + if (!g.currentMap.canExtend()) --g.mapDepth; + if (g.mapStates.isEmpty()) return; + if (g.mapStates.last().editBlock) endEditBlock(); g.mapStates.pop_back(); - if (g.mapStates.isEmpty()) - g.commandBuffer.setHistoryAutoSave(true); + if (g.mapStates.isEmpty()) g.commandBuffer.setHistoryAutoSave(true); } -bool FakeVimHandler::Private::canHandleMapping() -{ +bool FakeVimHandler::Private::canHandleMapping() { // Don't handle user mapping in sub-modes that cannot be followed by movement and in "noremap". - return g.subsubmode == NoSubSubMode - && g.submode != RegisterSubMode - && g.submode != WindowSubMode - && g.submode != ZSubMode - && g.submode != CapitalZSubMode - && g.submode != ReplaceSubMode - && g.submode != MacroRecordSubMode - && g.submode != MacroExecuteSubMode - && (g.mapStates.isEmpty() || !g.mapStates.last().noremap); + return g.subsubmode == NoSubSubMode && g.submode != RegisterSubMode && + g.submode != WindowSubMode && g.submode != ZSubMode && g.submode != CapitalZSubMode && + g.submode != ReplaceSubMode && g.submode != MacroRecordSubMode && + g.submode != MacroExecuteSubMode && + (g.mapStates.isEmpty() || !g.mapStates.last().noremap); } -void FakeVimHandler::Private::clearPendingInput() -{ +void FakeVimHandler::Private::clearPendingInput() { // Clear pending input on interrupt or bad mapping. g.pendingInput.clear(); g.mapStates.clear(); g.mapDepth = 0; // Clear all started edit blocks. - while (m_buffer->editBlockLevel > 0) - endEditBlock(); + while (m_buffer->editBlockLevel > 0) endEditBlock(); } -void FakeVimHandler::Private::waitForMapping() -{ +void FakeVimHandler::Private::waitForMapping() { g.currentCommand.clear(); foreach (const Input &input, g.currentMap.currentInputs()) g.currentCommand.append(input.toString()); @@ -3192,8 +2896,7 @@ void FakeVimHandler::Private::waitForMapping() m_inputTimer.start(); } -EventResult FakeVimHandler::Private::stopWaitForMapping(bool hasInput) -{ +EventResult FakeVimHandler::Private::stopWaitForMapping(bool hasInput) { if (!hasInput || m_inputTimer.isActive()) { m_inputTimer.stop(); g.currentCommand.clear(); @@ -3206,8 +2909,7 @@ EventResult FakeVimHandler::Private::stopWaitForMapping(bool hasInput) return EventHandled; } -void FakeVimHandler::Private::stopIncrementalFind() -{ +void FakeVimHandler::Private::stopIncrementalFind() { if (g.findPending) { g.findPending = false; setAnchorAndPosition(m_findStartPosition, m_cursor.selectionStart()); @@ -3216,18 +2918,15 @@ void FakeVimHandler::Private::stopIncrementalFind() } } -void FakeVimHandler::Private::updateFind(bool isComplete) -{ - if (!isComplete && !s.incSearch.value()) - return; +void FakeVimHandler::Private::updateFind(bool isComplete) { + if (!isComplete && !s.incSearch.value()) return; g.currentMessage.clear(); const QString &needle = g.searchBuffer.contents(); if (isComplete) { setPosition(m_searchStartPosition); - if (!needle.isEmpty()) - recordJump(); + if (!needle.isEmpty()) recordJump(); } SearchData sd; @@ -3237,84 +2936,65 @@ void FakeVimHandler::Private::updateFind(bool isComplete) search(sd, isComplete); } -void FakeVimHandler::Private::resetCount() -{ +void FakeVimHandler::Private::resetCount() { g.mvcount = 0; g.opcount = 0; } -bool FakeVimHandler::Private::isInputCount(const Input &input) const -{ +bool FakeVimHandler::Private::isInputCount(const Input &input) const { return input.isDigit() && (!input.is('0') || g.mvcount > 0); } -bool FakeVimHandler::Private::atEmptyLine(int pos) const -{ - return blockAt(pos).length() == 1; -} +bool FakeVimHandler::Private::atEmptyLine(int pos) const { return blockAt(pos).length() == 1; } -bool FakeVimHandler::Private::atEmptyLine(const QTextCursor &tc) const -{ +bool FakeVimHandler::Private::atEmptyLine(const QTextCursor &tc) const { return atEmptyLine(tc.position()); } -bool FakeVimHandler::Private::atEmptyLine() const -{ - return atEmptyLine(position()); -} +bool FakeVimHandler::Private::atEmptyLine() const { return atEmptyLine(position()); } bool FakeVimHandler::Private::atBoundary(bool end, bool simple, bool onlyWords, - const QTextCursor &tc) const -{ - if (tc.isNull()) - return atBoundary(end, simple, onlyWords, m_cursor); - if (atEmptyLine(tc)) - return true; + const QTextCursor &tc) const { + if (tc.isNull()) return atBoundary(end, simple, onlyWords, m_cursor); + if (atEmptyLine(tc)) return true; int pos = tc.position(); QChar c1 = characterAt(pos); QChar c2 = characterAt(pos + (end ? 1 : -1)); int thisClass = charClass(c1, simple); - return (!onlyWords || thisClass != 0) - && (c2.isNull() || c2 == ParagraphSeparator || thisClass != charClass(c2, simple)); + return (!onlyWords || thisClass != 0) && + (c2.isNull() || c2 == ParagraphSeparator || thisClass != charClass(c2, simple)); } -bool FakeVimHandler::Private::atWordBoundary(bool end, bool simple, const QTextCursor &tc) const -{ +bool FakeVimHandler::Private::atWordBoundary(bool end, bool simple, const QTextCursor &tc) const { return atBoundary(end, simple, true, tc); } -bool FakeVimHandler::Private::atWordStart(bool simple, const QTextCursor &tc) const -{ +bool FakeVimHandler::Private::atWordStart(bool simple, const QTextCursor &tc) const { return atWordBoundary(false, simple, tc); } -bool FakeVimHandler::Private::atWordEnd(bool simple, const QTextCursor &tc) const -{ +bool FakeVimHandler::Private::atWordEnd(bool simple, const QTextCursor &tc) const { return atWordBoundary(true, simple, tc); } -bool FakeVimHandler::Private::isFirstNonBlankOnLine(int pos) -{ +bool FakeVimHandler::Private::isFirstNonBlankOnLine(int pos) { for (int i = blockAt(pos).position(); i < pos; ++i) { - if (!document()->characterAt(i).isSpace()) - return false; + if (!document()->characterAt(i).isSpace()) return false; } return true; } -void FakeVimHandler::Private::pushUndoState(bool overwrite) -{ +void FakeVimHandler::Private::pushUndoState(bool overwrite) { if (m_buffer->editBlockLevel != 0 && m_buffer->undoState.isValid()) - return; // No need to save undo state for inner edit blocks. + return; // No need to save undo state for inner edit blocks. - if (m_buffer->undoState.isValid() && !overwrite) - return; + if (m_buffer->undoState.isValid() && !overwrite) return; UNDO_DEBUG("PUSH UNDO"); int pos = position(); if (!isInsertMode()) { - if (isVisualMode() || g.submode == DeleteSubMode - || (g.submode == ChangeSubMode && g.movetype != MoveLineWise)) { + if (isVisualMode() || g.submode == DeleteSubMode || + (g.submode == ChangeSubMode && g.movetype != MoveLineWise)) { pos = qMin(pos, anchor()); if (isVisualLineMode()) pos = firstPositionInLine(lineForPosition(pos)); @@ -3322,8 +3002,8 @@ void FakeVimHandler::Private::pushUndoState(bool overwrite) pos = blockAt(pos).position() + qMin(columnAt(anchor()), columnAt(position())); } else if (g.movetype == MoveLineWise && s.startOfLine.value()) { QTextCursor tc = m_cursor; - if (g.submode == ShiftLeftSubMode || g.submode == ShiftRightSubMode - || g.submode == IndentSubMode) { + if (g.submode == ShiftLeftSubMode || g.submode == ShiftRightSubMode || + g.submode == IndentSubMode) { pos = qMin(pos, anchor()); } tc.setPosition(pos); @@ -3336,15 +3016,12 @@ void FakeVimHandler::Private::pushUndoState(bool overwrite) setMark('.', lastChangePosition); m_buffer->redo.clear(); - m_buffer->undoState = State( - revision(), lastChangePosition, m_buffer->marks, - m_buffer->lastVisualMode, m_buffer->lastVisualModeInverted); + m_buffer->undoState = State(revision(), lastChangePosition, m_buffer->marks, + m_buffer->lastVisualMode, m_buffer->lastVisualModeInverted); } -void FakeVimHandler::Private::moveDown(int n) -{ - if (n == 0) - return; +void FakeVimHandler::Private::moveDown(int n) { + if (n == 0) return; QTextBlock block = m_cursor.block(); const int col = position() - block.position(); @@ -3355,8 +3032,7 @@ void FakeVimHandler::Private::moveDown(int n) position = block.position() + qMax(0, qMin(block.length() - 2, col)); if (block.isVisible()) { --lines; - if (lines < 0) - break; + if (lines < 0) break; } block = n > 0 ? nextLine(block) : previousLine(block); } @@ -3366,20 +3042,17 @@ void FakeVimHandler::Private::moveDown(int n) updateScrollOffset(); } -void FakeVimHandler::Private::moveDownVisually(int n) -{ +void FakeVimHandler::Private::moveDownVisually(int n) { const QTextCursor::MoveOperation moveOperation = (n > 0) ? Down : Up; int count = qAbs(n); int oldPos = m_cursor.position(); while (count > 0) { m_cursor.movePosition(moveOperation, KeepAnchor, 1); - if (oldPos == m_cursor.position()) - break; + if (oldPos == m_cursor.position()) break; oldPos = m_cursor.position(); QTextBlock block = m_cursor.block(); - if (block.isVisible()) - --count; + if (block.isVisible()) --count; } QTextCursor tc = m_cursor; @@ -3397,14 +3070,12 @@ void FakeVimHandler::Private::moveDownVisually(int n) m_targetColumnWrapped = targetColumn; } - if (!isInsertMode() && atEndOfLine()) - m_cursor.movePosition(Left, KeepAnchor); + if (!isInsertMode() && atEndOfLine()) m_cursor.movePosition(Left, KeepAnchor); updateScrollOffset(); } -void FakeVimHandler::Private::movePageDown(int count) -{ +void FakeVimHandler::Private::movePageDown(int count) { const int scrollOffset = windowScrollOffset(); const int screenLines = linesOnScreen(); const int offset = count > 0 ? scrollOffset - 2 : screenLines - scrollOffset + 2; @@ -3417,8 +3088,7 @@ void FakeVimHandler::Private::movePageDown(int count) scrollToLine(qMax(0, cursorLine() - screenLines + 1)); } -void FakeVimHandler::Private::commitCursor() -{ +void FakeVimHandler::Private::commitCursor() { QTextCursor tc = m_cursor; if (isVisualMode()) { @@ -3445,8 +3115,7 @@ void FakeVimHandler::Private::commitCursor() anc = lastPositionInLine(ancLine) + 1; } // putting cursor on folded line will unfold the line, so move the cursor a bit - if (!blockAt(pos).isVisible()) - ++pos; + if (!blockAt(pos).isVisible()) ++pos; } else if (isVisualCharMode()) { if (anc > pos) ++anc; @@ -3466,17 +3135,14 @@ void FakeVimHandler::Private::commitCursor() if (isVisualBlockMode()) { q->requestSetBlockSelection(tc); - } else { + } else { q->requestDisableBlockSelection(); - if (editor()) - EDITOR(setTextCursor(tc)); + if (editor()) EDITOR(setTextCursor(tc)); } } -void FakeVimHandler::Private::pullCursor() -{ - if (!m_cursorNeedsUpdate) - return; +void FakeVimHandler::Private::pullCursor() { + if (!m_cursorNeedsUpdate) return; m_cursorNeedsUpdate = false; @@ -3491,8 +3157,7 @@ void FakeVimHandler::Private::pullCursor() m_cursor = editorCursor(); // Cursor should be always valid. - if (m_cursor.isNull()) - m_cursor = QTextCursor(document()); + if (m_cursor.isNull()) m_cursor = QTextCursor(document()); if (visualBlockMode) g.visualMode = VisualBlockMode; @@ -3503,12 +3168,10 @@ void FakeVimHandler::Private::pullCursor() // Keep visually the text selection same. // With thick text cursor, the character under cursor is treated as selected. - if (isVisualCharMode() && hasThinCursor()) - moveLeft(); + if (isVisualCharMode() && hasThinCursor()) moveLeft(); // Cursor position can be after the end of line only in some modes. - if (atEndOfLine() && !isVisualMode() && !isInsertMode()) - moveLeft(); + if (atEndOfLine() && !isVisualMode() && !isInsertMode()) moveLeft(); // Record external jump to different line. if (lineForPosition(position()) != lineForPosition(oldCursor.position())) @@ -3517,38 +3180,31 @@ void FakeVimHandler::Private::pullCursor() setTargetColumn(); } -QTextCursor FakeVimHandler::Private::editorCursor() const -{ +QTextCursor FakeVimHandler::Private::editorCursor() const { QTextCursor tc = EDITOR(textCursor()); tc.setVisualNavigation(false); return tc; } -bool FakeVimHandler::Private::moveToNextParagraph(int count) -{ +bool FakeVimHandler::Private::moveToNextParagraph(int count) { const bool forward = count > 0; int repeat = forward ? count : -count; QTextBlock block = this->block(); - if (block.isValid() && block.length() == 1) - ++repeat; + if (block.isValid() && block.length() == 1) ++repeat; for (; block.isValid(); block = forward ? block.next() : block.previous()) { if (block.length() == 1) { - if (--repeat == 0) - break; + if (--repeat == 0) break; while (block.isValid() && block.length() == 1) block = forward ? block.next() : block.previous(); - if (!block.isValid()) - break; + if (!block.isValid()) break; } } - if (!block.isValid()) - --repeat; + if (!block.isValid()) --repeat; - if (repeat > 0) - return false; + if (repeat > 0) return false; if (block.isValid()) setPosition(block.position()); @@ -3558,8 +3214,7 @@ bool FakeVimHandler::Private::moveToNextParagraph(int count) return true; } -void FakeVimHandler::Private::moveToParagraphStartOrEnd(int direction) -{ +void FakeVimHandler::Private::moveToParagraphStartOrEnd(int direction) { bool emptyLine = atEmptyLine(); int oldPos = -1; @@ -3568,12 +3223,10 @@ void FakeVimHandler::Private::moveToParagraphStartOrEnd(int direction) moveDown(direction); } - if (oldPos != position()) - moveUp(direction); + if (oldPos != position()) moveUp(direction); } -void FakeVimHandler::Private::moveToEndOfLine() -{ +void FakeVimHandler::Private::moveToEndOfLine() { // Additionally select (in visual mode) or apply current command on hidden lines following // the current line. bool onlyVisibleLines = isVisualMode() || g.submode != NoSubMode; @@ -3582,50 +3235,41 @@ void FakeVimHandler::Private::moveToEndOfLine() setTargetColumn(); } -void FakeVimHandler::Private::moveToEndOfLineVisually() -{ +void FakeVimHandler::Private::moveToEndOfLineVisually() { moveToEndOfLineVisually(&m_cursor); setTargetColumn(); } -void FakeVimHandler::Private::moveToEndOfLineVisually(QTextCursor *tc) -{ +void FakeVimHandler::Private::moveToEndOfLineVisually(QTextCursor *tc) { // Moving to end of line ends up on following line if the line is wrapped. tc->movePosition(StartOfLine); const int minPos = tc->position(); tc->movePosition(EndOfLine); int maxPos = tc->position(); tc->movePosition(StartOfLine); - if (minPos != tc->position()) - --maxPos; + if (minPos != tc->position()) --maxPos; tc->setPosition(maxPos); } -void FakeVimHandler::Private::moveBehindEndOfLine() -{ +void FakeVimHandler::Private::moveBehindEndOfLine() { q->fold(1, false); - int pos = qMin(block().position() + block().length() - 1, - lastPositionInDocument() + 1); + int pos = qMin(block().position() + block().length() - 1, lastPositionInDocument() + 1); setPosition(pos); setTargetColumn(); } -void FakeVimHandler::Private::moveToStartOfLine() -{ +void FakeVimHandler::Private::moveToStartOfLine() { setPosition(block().position()); setTargetColumn(); } -void FakeVimHandler::Private::moveToStartOfLineVisually() -{ +void FakeVimHandler::Private::moveToStartOfLineVisually() { m_cursor.movePosition(StartOfLine, KeepAnchor); setTargetColumn(); } -void FakeVimHandler::Private::fixSelection() -{ - if (g.rangemode == RangeBlockMode) - return; +void FakeVimHandler::Private::fixSelection() { + if (g.rangemode == RangeBlockMode) return; if (g.movetype == MoveInclusive) { // If position or anchor is after end of non-empty line, include line break in selection. @@ -3660,14 +3304,11 @@ void FakeVimHandler::Private::fixSelection() } if (g.movetype == MoveLineWise) - g.rangemode = (g.submode == ChangeSubMode) - ? RangeLineModeExclusive - : RangeLineMode; + g.rangemode = (g.submode == ChangeSubMode) ? RangeLineModeExclusive : RangeLineMode; if (g.movetype == MoveInclusive) { if (anchor() <= position()) { - if (!atBlockEnd()) - setPosition(position() + 1); // correction + if (!atBlockEnd()) setPosition(position() + 1); // correction // Omit first character in selection if it's line break on non-empty line. int start = anchor(); @@ -3685,8 +3326,7 @@ void FakeVimHandler::Private::fixSelection() if (start < block().position() && isFirstNonBlankOnLine(start) && atBlockEnd()) { if (g.submode != ChangeSubMode) { moveRight(); - if (atEmptyLine()) - moveRight(); + if (atEmptyLine()) moveRight(); } g.movetype = MoveLineWise; } @@ -3710,20 +3350,17 @@ void FakeVimHandler::Private::fixSelection() } } -bool FakeVimHandler::Private::finishSearch() -{ - if (g.lastSearch.isEmpty() - || (!g.currentMessage.isEmpty() && g.currentMessageLevel == MessageError)) { +bool FakeVimHandler::Private::finishSearch() { + if (g.lastSearch.isEmpty() || + (!g.currentMessage.isEmpty() && g.currentMessageLevel == MessageError)) { return false; } - if (g.submode != NoSubMode) - setAnchorAndPosition(m_searchStartPosition, position()); + if (g.submode != NoSubMode) setAnchorAndPosition(m_searchStartPosition, position()); return true; } -void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) -{ - //dump("FINISH MOVEMENT"); +void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) { + // dump("FINISH MOVEMENT"); if (g.submode == FilterSubMode) { int beginLine = lineForPosition(anchor()); int endLine = lineForPosition(position()); @@ -3732,26 +3369,15 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) return; } - if (g.submode == ChangeSubMode - || g.submode == DeleteSubMode - || g.submode == CommentSubMode - || g.submode == ExchangeSubMode - || g.submode == ReplaceWithRegisterSubMode - || g.submode == AddSurroundingSubMode - || g.submode == YankSubMode - || g.submode == InvertCaseSubMode - || g.submode == DownCaseSubMode - || g.submode == UpCaseSubMode - || g.submode == IndentSubMode - || g.submode == ShiftLeftSubMode - || g.submode == ShiftRightSubMode) - { + if (g.submode == ChangeSubMode || g.submode == DeleteSubMode || g.submode == CommentSubMode || + g.submode == ExchangeSubMode || g.submode == ReplaceWithRegisterSubMode || + g.submode == AddSurroundingSubMode || g.submode == YankSubMode || + g.submode == InvertCaseSubMode || g.submode == DownCaseSubMode || + g.submode == UpCaseSubMode || g.submode == IndentSubMode || g.submode == ShiftLeftSubMode || + g.submode == ShiftRightSubMode) { fixSelection(); - if (g.submode == ChangeSubMode - || g.submode == DeleteSubMode - || g.submode == YankSubMode) - { + if (g.submode == ChangeSubMode || g.submode == DeleteSubMode || g.submode == YankSubMode) { yankText(currentRange(), m_register); } } @@ -3760,8 +3386,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) pushUndoState(false); beginEditBlock(); removeText(currentRange()); - if (g.movetype == MoveLineWise) - insertAutomaticIndentation(true); + if (g.movetype == MoveLineWise) insertAutomaticIndentation(true); endEditBlock(); setTargetColumn(); } else if (g.submode == CommentSubMode) { @@ -3794,8 +3419,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) removeText(Range(pos, pos + 1)); else removeText(currentRange()); - if (g.movetype == MoveLineWise) - handleStartOfLine(); + if (g.movetype == MoveLineWise) handleStartOfLine(); endEditBlock(); } else if (g.submode == YankSubMode) { bool isVisualModeYank = isVisualMode(); @@ -3816,9 +3440,8 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) } } setTargetColumn(); - } else if (g.submode == InvertCaseSubMode - || g.submode == UpCaseSubMode - || g.submode == DownCaseSubMode) { + } else if (g.submode == InvertCaseSubMode || g.submode == UpCaseSubMode || + g.submode == DownCaseSubMode) { beginEditBlock(); if (g.submode == InvertCaseSubMode) invertCase(currentRange()); @@ -3826,12 +3449,10 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) downCase(currentRange()); else if (g.submode == UpCaseSubMode) upCase(currentRange()); - if (g.movetype == MoveLineWise) - handleStartOfLine(); + if (g.movetype == MoveLineWise) handleStartOfLine(); endEditBlock(); - } else if (g.submode == IndentSubMode - || g.submode == ShiftRightSubMode - || g.submode == ShiftLeftSubMode) { + } else if (g.submode == IndentSubMode || g.submode == ShiftRightSubMode || + g.submode == ShiftLeftSubMode) { recordJump(); pushUndoState(false); if (g.submode == IndentSubMode) @@ -3861,8 +3482,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) } } -void FakeVimHandler::Private::leaveCurrentMode() -{ +void FakeVimHandler::Private::leaveCurrentMode() { if (isVisualMode()) enterCommandMode(g.returnToMode); else if (g.returnToMode == CommandMode) @@ -3872,12 +3492,10 @@ void FakeVimHandler::Private::leaveCurrentMode() else enterReplaceMode(); - if (isNoVisualMode()) - setAnchor(); + if (isNoVisualMode()) setAnchor(); } -void FakeVimHandler::Private::clearCurrentMode() -{ +void FakeVimHandler::Private::clearCurrentMode() { g.submode = NoSubMode; g.subsubmode = NoSubSubMode; g.movetype = MoveInclusive; @@ -3890,8 +3508,7 @@ void FakeVimHandler::Private::clearCurrentMode() resetCount(); } -void FakeVimHandler::Private::updateSelection() -{ +void FakeVimHandler::Private::updateSelection() { QList selections = m_extraSelections; if (s.showMarks.value()) { for (auto it = m_buffer->marks.cbegin(), end = m_buffer->marks.cend(); it != end; ++it) { @@ -3906,15 +3523,13 @@ void FakeVimHandler::Private::updateSelection() selections.append(sel); } } - //qDebug() << "SELECTION: " << selections; + // qDebug() << "SELECTION: " << selections; q->selectionChanged(selections); } -void FakeVimHandler::Private::updateHighlights() -{ +void FakeVimHandler::Private::updateHighlights() { if (s.useCoreSearch.value() || !s.hlSearch.value() || g.highlightsCleared) { - if (m_highlighted.isEmpty()) - return; + if (m_highlighted.isEmpty()) return; m_highlighted.clear(); } else if (m_highlighted != g.lastNeedle) { m_highlighted = g.lastNeedle; @@ -3925,10 +3540,8 @@ void FakeVimHandler::Private::updateHighlights() q->highlightMatches(m_highlighted); } -void FakeVimHandler::Private::updateMiniBuffer() -{ - if (!m_textedit && !m_plaintextedit) - return; +void FakeVimHandler::Private::updateMiniBuffer() { + if (!m_textedit && !m_plaintextedit) return; QString msg; int cursorPos = -1; @@ -3986,16 +3599,14 @@ void FakeVimHandler::Private::updateMiniBuffer() msg = "-- (replace) --"; } - if (g.isRecording && msg.startsWith("--")) - msg.append(' ').append("Recording"); + if (g.isRecording && msg.startsWith("--")) msg.append(' ').append("Recording"); q->commandBufferChanged(msg, cursorPos, anchorPos, messageLevel); int linesInDoc = linesInDocument(); int l = cursorLine(); QString status; - const QString pos = QStringLiteral("%1,%2") - .arg(l + 1).arg(physicalCursorColumn() + 1); + const QString pos = QStringLiteral("%1,%2").arg(l + 1).arg(physicalCursorColumn() + 1); // FIXME: physical "-" logical if (linesInDoc != 0) status = Tr::tr("%1%2%").arg(pos, -10).arg(l * 100 / linesInDoc, 4); @@ -4004,21 +3615,18 @@ void FakeVimHandler::Private::updateMiniBuffer() q->statusDataChanged(status); } -void FakeVimHandler::Private::showMessage(MessageLevel level, const QString &msg) -{ - //qDebug() << "MSG: " << msg; +void FakeVimHandler::Private::showMessage(MessageLevel level, const QString &msg) { + // qDebug() << "MSG: " << msg; g.currentMessage = msg; g.currentMessageLevel = level; } -void FakeVimHandler::Private::notImplementedYet() -{ +void FakeVimHandler::Private::notImplementedYet() { qDebug() << "Not implemented in FakeVim"; showMessage(MessageError, Tr::tr("Not implemented in FakeVim.")); } -void FakeVimHandler::Private::passShortcuts(bool enable) -{ +void FakeVimHandler::Private::passShortcuts(bool enable) { g.passing = enable; updateMiniBuffer(); if (enable) @@ -4027,8 +3635,7 @@ void FakeVimHandler::Private::passShortcuts(bool enable) QCoreApplication::instance()->removeEventFilter(q); } -bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) { bool handled = true; if (g.subsubmode == FtSubSubMode) { @@ -4038,14 +3645,14 @@ bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) g.subsubmode = NoSubSubMode; if (handled) { finishMovement(QStringLiteral("%1%2%3") - .arg(count()) - .arg(g.semicolonType.text()) - .arg(g.semicolonKey)); + .arg(count()) + .arg(g.semicolonType.text()) + .arg(g.semicolonKey)); } } else if (g.subsubmode == TextObjectSubSubMode) { // vim-surround treats aw and aW the same as iw and iW, respectively - if ((input.is('w') || input.is('W')) - && g.submode == AddSurroundingSubMode && g.subsubdata.is('a')) + if ((input.is('w') || input.is('W')) && g.submode == AddSurroundingSubMode && + g.subsubdata.is('a')) g.subsubdata = Input('i'); if (input.is('w')) @@ -4072,19 +3679,15 @@ bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) handled = false; g.subsubmode = NoSubSubMode; if (handled) { - finishMovement(QStringLiteral("%1%2%3") - .arg(count()) - .arg(g.subsubdata.text()) - .arg(input.text())); + finishMovement( + QStringLiteral("%1%2%3").arg(count()).arg(g.subsubdata.text()).arg(input.text())); } } else if (g.subsubmode == MarkSubSubMode) { setMark(input.asChar(), CursorPosition(m_cursor)); g.subsubmode = NoSubSubMode; - } else if (g.subsubmode == BackTickSubSubMode - || g.subsubmode == TickSubSubMode) { + } else if (g.subsubmode == BackTickSubSubMode || g.subsubmode == TickSubSubMode) { handled = jumpToMark(input.asChar(), g.subsubmode == BackTickSubSubMode); - if (handled) - finishMovement(); + if (handled) finishMovement(); g.subsubmode = NoSubSubMode; } else if (g.subsubmode == ZSubSubMode) { handled = false; @@ -4093,9 +3696,7 @@ bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) q->foldGoTo(input.is('j') ? count() : -count(), false); if (pos != position()) { handled = true; - finishMovement(QStringLiteral("%1z%2") - .arg(count()) - .arg(input.text())); + finishMovement(QStringLiteral("%1z%2").arg(count()).arg(input.text())); } } } else if (g.subsubmode == OpenSquareSubSubMode || g.subsubmode == CloseSquareSubSubMode) { @@ -4120,12 +3721,11 @@ bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) q->foldGoTo(g.subsubmode == OpenSquareSubSubMode ? -count() : count(), true); handled = pos != position(); if (handled) { - if (lineForPosition(pos) != lineForPosition(position())) - recordJump(pos); + if (lineForPosition(pos) != lineForPosition(position())) recordJump(pos); finishMovement(QStringLiteral("%1%2%3") - .arg(count()) - .arg(g.subsubmode == OpenSquareSubSubMode ? '[' : ']') - .arg(input.text())); + .arg(count()) + .arg(g.subsubmode == OpenSquareSubSubMode ? '[' : ']') + .arg(input.text())); } } else if (g.subsubmode == SurroundWithFunctionSubSubMode) { if (input.isReturn()) { @@ -4164,16 +3764,13 @@ bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) return handled; } -bool FakeVimHandler::Private::handleCount(const Input &input) -{ - if (!isInputCount(input)) - return false; +bool FakeVimHandler::Private::handleCount(const Input &input) { + if (!isInputCount(input)) return false; g.mvcount = g.mvcount * 10 + input.text().toInt(); return true; } -bool FakeVimHandler::Private::handleMovement(const Input &input) -{ +bool FakeVimHandler::Private::handleMovement(const Input &input) { bool handled = true; int count = this->count(); @@ -4199,7 +3796,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) // FIXME: fakevim uses ',' by itself, so it is incompatible g.subsubmode = FtSubSubMode; // HACK: toggle 'f' <-> 'F', 't' <-> 'T' - //g.subsubdata = g.semicolonType ^ 32; + // g.subsubdata = g.semicolonType ^ 32; handleFfTt(g.semicolonKey, true); g.subsubmode = NoSubSubMode; } else if (input.is(';')) { @@ -4214,7 +3811,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) g.findPending = true; m_findStartPosition = position(); g.movetype = MoveExclusive; - setAnchor(); // clear selection: otherwise, search is restricted to selection + setAnchor(); // clear selection: otherwise, search is restricted to selection q->findRequested(!g.lastSearchForward); } else { // FIXME: make core find dialog sufficiently flexible to @@ -4247,8 +3844,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) handled = searchNext(); } else if (input.is('\'')) { g.subsubmode = TickSubSubMode; - if (g.submode != NoSubMode) - g.movetype = MoveLineWise; + if (g.submode != NoSubMode) g.movetype = MoveLineWise; } else if (input.is('|')) { moveToStartOfLine(); const int column = count - 1; @@ -4257,9 +3853,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) m_visualTargetColumn = column; } else if (input.is('{') || input.is('}')) { const int oldPosition = position(); - handled = input.is('}') - ? moveToNextParagraph(count) - : moveToPreviousParagraph(count); + handled = input.is('}') ? moveToNextParagraph(count) : moveToPreviousParagraph(count); if (handled) { recordJump(oldPosition); setTargetColumn(); @@ -4281,19 +3875,15 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) moveToStartOfLine(); } else if (input.is('$') || input.isKey(Key_End)) { if (g.gflag) { - if (count > 1) - moveDownVisually(count - 1); + if (count > 1) moveDownVisually(count - 1); moveToEndOfLineVisually(); } else { - if (count > 1) - moveDown(count - 1); + if (count > 1) moveDown(count - 1); moveToEndOfLine(); } g.movetype = atEmptyLine() ? MoveExclusive : MoveInclusive; - if (g.submode == NoSubMode) - m_targetColumn = -1; - if (isVisualMode()) - m_visualTargetColumn = -1; + if (g.submode == NoSubMode) m_targetColumn = -1; + if (isVisualMode()) m_visualTargetColumn = -1; } else if (input.is('%')) { recordJump(); if (g.mvcount == 0) { @@ -4320,8 +3910,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) moveToNextWordEnd(count, true, true, false); } else if (input.isControl('e')) { // FIXME: this should use the "scroll" option, and "count" - if (cursorLineOnScreen() == 0) - moveDown(1); + if (cursorLineOnScreen() == 0) moveDown(1); scrollDown(1); } else if (input.is('f')) { g.subsubmode = FtSubSubMode; @@ -4337,12 +3926,11 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) } else if (input.is('g') || input.is('G')) { QString dotCommand = QStringLiteral("%1G").arg(count); recordJump(); - if (input.is('G') && g.mvcount == 0) - dotCommand = "G"; + if (input.is('G') && g.mvcount == 0) dotCommand = "G"; int n = (input.is('g')) ? 1 : linesInDocument(); n = g.mvcount == 0 ? n : count; - if (g.submode == NoSubMode || g.submode == ZSubMode - || g.submode == CapitalZSubMode || g.submode == RegisterSubMode) { + if (g.submode == NoSubMode || g.submode == ZSubMode || g.submode == CapitalZSubMode || + g.submode == RegisterSubMode) { setPosition(firstPositionInLine(n, false)); handleStartOfLine(); } else { @@ -4361,8 +3949,8 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) const CursorPosition pos(lineToBlockNumber(lineOnTop(count)), 0); setCursorPosition(&m_cursor, pos); handleStartOfLine(); - } else if (input.is('j') || input.isKey(Key_Down) - || input.isControl('j') || input.isControl('n')) { + } else if (input.is('j') || input.isKey(Key_Down) || input.isControl('j') || + input.isControl('n')) { moveVertically(count); } else if (input.is('k') || input.isKey(Key_Up) || input.isControl('p')) { moveVertically(-count); @@ -4404,8 +3992,8 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) g.movetype = MoveExclusive; g.subsubmode = FtSubSubMode; g.subsubdata = input; - } else if (input.is('w') || input.is('W') - || input.isShift(Key_Right) || input.isControl(Key_Right)) { // tested + } else if (input.is('w') || input.is('W') || input.isShift(Key_Right) || + input.isControl(Key_Right)) { // tested // Special case: "cw" and "cW" work the same as "ce" and "cE" if the // cursor is on a non-blank - except if the cursor is on the last // character of a word: only the current word will be changed @@ -4421,7 +4009,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) } } } else if (input.is('z')) { - g.movetype = MoveLineWise; + g.movetype = MoveLineWise; g.subsubmode = ZSubSubMode; } else if (input.is('[')) { g.subsubmode = OpenSquareSubSubMode; @@ -4442,10 +4030,8 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) leaveCurrentMode(); } else { // finish movement for sub modes - const QString dotMovement = - (count > 1 ? QString::number(count) : QString()) - + QLatin1String(g.gflag ? "g" : "") - + input.toString(); + const QString dotMovement = (count > 1 ? QString::number(count) : QString()) + + QLatin1String(g.gflag ? "g" : "") + input.toString(); finishMovement(dotMovement); setTargetColumn(); } @@ -4454,8 +4040,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) return handled; } -EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) -{ +EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) { bool handled = false; bool clearGflag = g.gflag; @@ -4477,33 +4062,30 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) // Exchange submode is "cx", so we need to switch over from ChangeSubMode here g.submode = ExchangeSubMode; handled = true; - } else if (g.submode == DeleteSurroundingSubMode - || g.submode == ChangeSurroundingSubMode) { + } else if (g.submode == DeleteSurroundingSubMode || g.submode == ChangeSurroundingSubMode) { handled = handleDeleteChangeSurroundingSubMode(input); } else if (g.submode == AddSurroundingSubMode) { handled = handleAddSurroundingSubMode(input); - } else if (g.submode == ChangeSubMode && (input.is('s') || input.is('S')) - && s.emulateSurround.value()) { + } else if (g.submode == ChangeSubMode && (input.is('s') || input.is('S')) && + s.emulateSurround.value()) { g.submode = ChangeSurroundingSubMode; g.surroundUpperCaseS = input.is('S'); handled = true; } else if (g.submode == DeleteSubMode && input.is('s') && s.emulateSurround.value()) { g.submode = DeleteSurroundingSubMode; handled = true; - } else if (g.submode == YankSubMode && (input.is('s') || input.is('S')) - && s.emulateSurround.value()) { + } else if (g.submode == YankSubMode && (input.is('s') || input.is('S')) && + s.emulateSurround.value()) { g.submode = AddSurroundingSubMode; g.movetype = MoveInclusive; g.surroundUpperCaseS = input.is('S'); handled = true; - } else if (g.submode == ChangeSubMode - || g.submode == DeleteSubMode - || g.submode == YankSubMode) { + } else if (g.submode == ChangeSubMode || g.submode == DeleteSubMode || + g.submode == YankSubMode) { handled = handleChangeDeleteYankSubModes(input); } else if (g.submode == CommentSubMode && s.emulateVimCommentary.value()) { handled = handleCommentSubMode(input); - } else if (g.submode == ReplaceWithRegisterSubMode - && s.emulateReplaceWithRegister.value()) { + } else if (g.submode == ReplaceWithRegisterSubMode && s.emulateReplaceWithRegister.value()) { handled = handleReplaceWithRegisterSubMode(input); } else if (g.submode == ReplaceSubMode) { handled = handleReplaceSubMode(input); @@ -4521,18 +4103,15 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) handled = handleMacroRecordSubMode(input); } else if (g.submode == MacroExecuteSubMode) { handled = handleMacroExecuteSubMode(input); - } else if (g.submode == ShiftLeftSubMode - || g.submode == ShiftRightSubMode - || g.submode == IndentSubMode) { + } else if (g.submode == ShiftLeftSubMode || g.submode == ShiftRightSubMode || + g.submode == IndentSubMode) { handled = handleShiftSubMode(input); - } else if (g.submode == InvertCaseSubMode - || g.submode == DownCaseSubMode - || g.submode == UpCaseSubMode) { + } else if (g.submode == InvertCaseSubMode || g.submode == DownCaseSubMode || + g.submode == UpCaseSubMode) { handled = handleChangeCaseSubMode(input); } - if (!handled && isOperatorPending()) - handled = handleMovement(input); + if (!handled && isOperatorPending()) handled = handleMovement(input); // Clear state and display incomplete command if necessary. if (handled) { @@ -4543,11 +4122,9 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) leaveCurrentMode(); } else { // Use gflag only for next input. - if (clearGflag) - g.gflag = false; + if (clearGflag) g.gflag = false; // Clear [count] and [register] if its no longer needed. - if (clearCount) - resetCount(); + if (clearCount) resetCount(); // Show or clear current command on minibuffer (showcmd). if (input.isEscape() || g.mode != CommandMode || clearCount) g.currentCommand.clear(); @@ -4558,13 +4135,12 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) saveLastVisualMode(); } else { leaveCurrentMode(); - //qDebug() << "IGNORED IN COMMAND MODE: " << key << text - // << " VISUAL: " << g.visualMode; + // qDebug() << "IGNORED IN COMMAND MODE: " << key << text + // << " VISUAL: " << g.visualMode; // if a key which produces text was pressed, don't mark it as unhandled // - otherwise the text would be inserted while being in command mode - if (input.text().isEmpty()) - handled = false; + if (input.text().isEmpty()) handled = false; } m_positionPastEnd = (m_visualTargetColumn == -1) && isVisualMode() && !atEmptyLine(); @@ -4572,23 +4148,18 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) return handled ? EventHandled : EventCancelled; } -bool FakeVimHandler::Private::handleEscape() -{ - if (isVisualMode()) - leaveVisualMode(); +bool FakeVimHandler::Private::handleEscape() { + if (isVisualMode()) leaveVisualMode(); leaveCurrentMode(); return true; } -bool FakeVimHandler::Private::handleNoSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleNoSubMode(const Input &input) { bool handled = true; const int oldRevision = revision(); - QString dotCommand = visualDotCommand() - + QLatin1String(g.gflag ? "g" : "") - + QString::number(count()) - + input.toString(); + QString dotCommand = visualDotCommand() + QLatin1String(g.gflag ? "g" : "") + + QString::number(count()) + input.toString(); if (input.is('&')) { handleExCommand(QLatin1String(g.gflag ? "%s//~/&" : "s")); @@ -4603,8 +4174,8 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) } else if (input.is(',')) { passShortcuts(true); } else if (input.is('.')) { - //qDebug() << "REPEATING" << quoteUnprintable(g.dotCommand) << count() - // << input; + // qDebug() << "REPEATING" << quoteUnprintable(g.dotCommand) << count() + // << input; dotCommand.clear(); QString savedCommand = g.dotCommand; g.dotCommand.clear(); @@ -4630,8 +4201,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) } } else if ((!isVisualMode() && input.is('a')) || (isVisualMode() && input.is('A'))) { if (isVisualMode()) { - if (!isVisualBlockMode()) - dotCommand = QString::number(count()) + "a"; + if (!isVisualBlockMode()) dotCommand = QString::number(count()) + "a"; enterVisualInsertMode('A'); } else { moveRight(qMin(rightDist(), 1)); @@ -4686,8 +4256,8 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) g.rangemode = RangeCharMode; g.movetype = MoveExclusive; g.submode = changeDeleteYankModeFromInput(input); - } else if ((input.is('c') || input.is('C') || input.is('s') || input.is('R')) - && (isVisualCharMode() || isVisualLineMode())) { + } else if ((input.is('c') || input.is('C') || input.is('s') || input.is('R')) && + (isVisualCharMode() || isVisualLineMode())) { leaveVisualMode(); g.submode = ChangeSubMode; finishMovement(); @@ -4699,23 +4269,21 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) } else if (input.isControl('c')) { if (isNoVisualMode()) { #if defined(Q_OS_MACOS) - showMessage(MessageInfo, Tr::tr("Type Meta-Shift-Y, Meta-Shift-Y to quit FakeVim mode.")); + showMessage(MessageInfo, + Tr::tr("Type Meta-Shift-Y, Meta-Shift-Y to quit FakeVim mode.")); #else showMessage(MessageInfo, Tr::tr("Type Alt-Y, Alt-Y to quit FakeVim mode.")); #endif } else { leaveVisualMode(); } - } else if ((input.is('d') || input.is('x') || input.isKey(Key_Delete)) - && isVisualMode()) { + } else if ((input.is('d') || input.is('x') || input.isKey(Key_Delete)) && isVisualMode()) { cutSelectedText(); } else if (input.is('D') && isNoVisualMode()) { handleAs("%1d$"); } else if ((input.is('D') || input.is('X')) && isVisualMode()) { - if (isVisualCharMode()) - toggleVisualMode(VisualLineMode); - if (isVisualBlockMode() && input.is('D')) - m_visualTargetColumn = -1; + if (isVisualCharMode()) toggleVisualMode(VisualLineMode); + if (isVisualBlockMode() && input.is('D')) m_visualTargetColumn = -1; cutSelectedText(); } else if (input.isControl('d')) { const int scrollOffset = windowScrollOffset(); @@ -4729,12 +4297,10 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) } else if (!isVisualMode() && (input.is('i') || input.isKey(Key_Insert))) { breakEditBlock(); enterInsertMode(); - if (atEndOfLine()) - moveLeft(); + if (atEndOfLine()) moveLeft(); } else if (input.is('I')) { if (isVisualMode()) { - if (!isVisualBlockMode()) - dotCommand = QString::number(count()) + "i"; + if (!isVisualBlockMode()) dotCommand = QString::number(count()) + "i"; enterVisualInsertMode('I'); } else { if (g.gflag) @@ -4750,8 +4316,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) pushUndoState(); moveBehindEndOfLine(); beginEditBlock(); - if (g.submode == NoSubMode) - joinLines(count(), g.gflag); + if (g.submode == NoSubMode) joinLines(count(), g.gflag); endEditBlock(); } else if (input.isControl('l')) { // screen redraw. should not be needed @@ -4762,8 +4327,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) setAnchorAndPosition(pos, anchor()); std::swap(m_positionPastEnd, m_anchorPastEnd); setTargetColumn(); - if (m_positionPastEnd) - m_visualTargetColumn = -1; + if (m_positionPastEnd) m_visualTargetColumn = -1; } else if (input.is('o') || input.is('O')) { bool insertAfter = input.is('o'); pushUndoState(); @@ -4797,14 +4361,14 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) // Close accidentally opened block. if (block().blockNumber() > 0) { moveUp(); - if (line != lineNumber(block())) - q->fold(1, true); + if (line != lineNumber(block())) q->fold(1, true); moveDown(); } } else if (input.isControl('o')) { jump(-count()); } else if (input.is('p') || input.is('P') || input.isShift(Qt::Key_Insert)) { - dotCommand = QStringLiteral("\"%1%2%3").arg(QChar(m_register)).arg(count()).arg(input.asChar()); + dotCommand = + QStringLiteral("\"%1%2%3").arg(QChar(m_register)).arg(count()).arg(input.asChar()); pasteText(!input.is('P')); setTargetColumn(); @@ -4816,8 +4380,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) } else { // Recording shouldn't work in mapping or while executing register. handled = g.mapStates.empty(); - if (handled) - g.submode = MacroRecordSubMode; + if (handled) g.submode = MacroRecordSubMode; } } else if (input.is('r')) { g.submode = ReplaceSubMode; @@ -4828,8 +4391,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) } else if (input.isControl('r')) { dotCommand.clear(); int repeat = count(); - while (--repeat >= 0) - redo(); + while (--repeat >= 0) redo(); } else if (input.is('S') && isVisualMode() && s.emulateSurround.value()) { g.submode = AddSurroundingSubMode; g.subsubmode = SurroundSubSubMode; @@ -4846,8 +4408,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) } else if (!g.gflag && input.is('u') && !isVisualMode()) { dotCommand.clear(); int repeat = count(); - while (--repeat >= 0) - undo(); + while (--repeat >= 0) undo(); } else if (input.isControl('u')) { int sline = cursorLineOnScreen(); // FIXME: this should use the "scroll" option, and "count" @@ -4858,8 +4419,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) if (isNoVisualMode()) { CursorPosition from = markLessPosition(); CursorPosition to = markGreaterPosition(); - if (m_buffer->lastVisualModeInverted) - std::swap(from, to); + if (m_buffer->lastVisualModeInverted) std::swap(from, to); toggleVisualMode(m_buffer->lastVisualMode); setCursorPosition(from); setAnchor(); @@ -4880,21 +4440,19 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) changeNumberTextObject(-count()); } else if (input.is('X')) { handleAs("%1dh"); - } else if (input.is('Y') && isNoVisualMode()) { + } else if (input.is('Y') && isNoVisualMode()) { handleAs("%1yy"); } else if (input.isControl('y')) { // FIXME: this should use the "scroll" option, and "count" - if (cursorLineOnScreen() == linesOnScreen() - 1) - moveUp(1); + if (cursorLineOnScreen() == linesOnScreen() - 1) moveUp(1); scrollUp(1); } else if (input.is('y') && isVisualCharMode()) { g.rangemode = RangeCharMode; g.movetype = MoveInclusive; g.submode = YankSubMode; finishMovement(); - } else if ((input.is('y') && isVisualLineMode()) - || (input.is('Y') && isVisualLineMode()) - || (input.is('Y') && isVisualCharMode())) { + } else if ((input.is('y') && isVisualLineMode()) || (input.is('Y') && isVisualLineMode()) || + (input.is('Y') && isVisualCharMode())) { g.rangemode = RangeLineMode; g.movetype = MoveLineWise; g.submode = YankSubMode; @@ -4916,8 +4474,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) leaveVisualMode(); finishMovement(); } else if (g.gflag || (g.submode == InvertCaseSubMode && s.tildeOp.value())) { - if (atEndOfLine()) - moveLeft(); + if (atEndOfLine()) moveLeft(); setAnchor(); } else { const QString movementCommand = QStringLiteral("%1l%1l").arg(count()); @@ -4929,8 +4486,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) setAnchor(); moveRight(qMin(1, rightDist())); removeText(currentRange()); - if (atEndOfLine()) - moveLeft(); + if (atEndOfLine()) moveLeft(); } else if (input.isControl(Key_BracketRight)) { handleExCommand("tag"); } else if (handleMovement(input)) { @@ -4947,40 +4503,34 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) return handled; } -bool FakeVimHandler::Private::handleChangeDeleteYankSubModes(const Input &input) -{ - if (g.submode != changeDeleteYankModeFromInput(input)) - return false; +bool FakeVimHandler::Private::handleChangeDeleteYankSubModes(const Input &input) { + if (g.submode != changeDeleteYankModeFromInput(input)) return false; handleChangeDeleteYankSubModes(); return true; } -void FakeVimHandler::Private::handleChangeDeleteYankSubModes() -{ +void FakeVimHandler::Private::handleChangeDeleteYankSubModes() { g.movetype = MoveLineWise; const QString dotCommand = dotCommandFromSubMode(g.submode); - if (!dotCommand.isEmpty()) - pushUndoState(); + if (!dotCommand.isEmpty()) pushUndoState(); const int anc = firstPositionInLine(cursorLine() + 1); moveDown(count() - 1); const int pos = lastPositionInLine(cursorLine() + 1); setAnchorAndPosition(anc, pos); - if (!dotCommand.isEmpty()) - setDotCommand(QStringLiteral("%2%1%1").arg(dotCommand), count()); + if (!dotCommand.isEmpty()) setDotCommand(QStringLiteral("%2%1%1").arg(dotCommand), count()); finishMovement(); g.submode = NoSubMode; } -bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input) { bool handled = true; const QChar c = input.asChar(); @@ -4989,8 +4539,7 @@ bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input) pushUndoState(); leaveVisualMode(); Range range = currentRange(); - if (g.rangemode == RangeCharMode) - ++range.endPos; + if (g.rangemode == RangeCharMode) ++range.endPos; // Replace each character but preserve lines. transformText(range, [&c](const QString &text) { return QString(text).replace(QRegularExpression("[^\\n]"), c); @@ -5020,10 +4569,8 @@ bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input) return handled; } -bool FakeVimHandler::Private::handleCommentSubMode(const Input &input) -{ - if (!input.is('c')) - return false; +bool FakeVimHandler::Private::handleCommentSubMode(const Input &input) { + if (!input.is('c')) return false; g.movetype = MoveLineWise; @@ -5041,16 +4588,13 @@ bool FakeVimHandler::Private::handleCommentSubMode(const Input &input) return true; } -bool FakeVimHandler::Private::handleReplaceWithRegisterSubMode(const Input &input) -{ - if (!input.is('r')) - return false; +bool FakeVimHandler::Private::handleReplaceWithRegisterSubMode(const Input &input) { + if (!input.is('r')) return false; pushUndoState(false); beginEditBlock(); - const QString movement = (count() == 1) - ? QString() : (QString::number(count() - 1) + "j"); + const QString movement = (count() == 1) ? QString() : (QString::number(count() - 1) + "j"); g.dotCommand = "V" + movement + "gr"; replay(g.dotCommand); @@ -5060,15 +4604,14 @@ bool FakeVimHandler::Private::handleReplaceWithRegisterSubMode(const Input &inpu return true; } -bool FakeVimHandler::Private::handleExchangeSubMode(const Input &input) -{ - if (input.is('c')) { // cxc +bool FakeVimHandler::Private::handleExchangeSubMode(const Input &input) { + if (input.is('c')) { // cxc g.exchangeRange.reset(); g.submode = NoSubMode; return true; } - if (input.is('x')) { // cxx + if (input.is('x')) { // cxx setAnchorAndPosition(firstPositionInLine(cursorLine() + 1), lastPositionInLine(cursorLine() + 1) + 1); @@ -5084,8 +4627,7 @@ bool FakeVimHandler::Private::handleExchangeSubMode(const Input &input) return false; } -bool FakeVimHandler::Private::handleDeleteChangeSurroundingSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleDeleteChangeSurroundingSubMode(const Input &input) { if (g.submode != ChangeSurroundingSubMode && g.submode != DeleteSurroundingSubMode) return false; @@ -5109,9 +4651,8 @@ bool FakeVimHandler::Private::handleDeleteChangeSurroundingSubMode(const Input & beginEditBlock(); // Surround is always one character, so just delete the first and last one - transformText(currentRange(), [](const QString &text) { - return text.mid(1, text.size() - 2); - }); + transformText(currentRange(), + [](const QString &text) { return text.mid(1, text.size() - 2); }); endEditBlock(); clearCurrentMode(); @@ -5125,10 +4666,8 @@ bool FakeVimHandler::Private::handleDeleteChangeSurroundingSubMode(const Input & return handled; } -bool FakeVimHandler::Private::handleAddSurroundingSubMode(const Input &input) -{ - if (!input.is('s')) - return false; +bool FakeVimHandler::Private::handleAddSurroundingSubMode(const Input &input) { + if (!input.is('s')) return false; g.subsubmode = SurroundSubSubMode; @@ -5147,13 +4686,9 @@ bool FakeVimHandler::Private::handleAddSurroundingSubMode(const Input &input) return true; } -bool FakeVimHandler::Private::handleFilterSubMode(const Input &) -{ - return false; -} +bool FakeVimHandler::Private::handleFilterSubMode(const Input &) { return false; } -bool FakeVimHandler::Private::handleRegisterSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleRegisterSubMode(const Input &input) { bool handled = false; QChar reg = input.asChar(); @@ -5166,10 +4701,8 @@ bool FakeVimHandler::Private::handleRegisterSubMode(const Input &input) return handled; } -bool FakeVimHandler::Private::handleShiftSubMode(const Input &input) -{ - if (g.submode != indentModeFromInput(input)) - return false; +bool FakeVimHandler::Private::handleShiftSubMode(const Input &input) { + if (g.submode != indentModeFromInput(input)) return false; g.movetype = MoveLineWise; pushUndoState(); @@ -5181,10 +4714,8 @@ bool FakeVimHandler::Private::handleShiftSubMode(const Input &input) return true; } -bool FakeVimHandler::Private::handleChangeCaseSubMode(const Input &input) -{ - if (g.submode != letterCaseModeFromInput(input)) - return false; +bool FakeVimHandler::Private::handleChangeCaseSubMode(const Input &input) { + if (g.submode != letterCaseModeFromInput(input)) return false; if (!isFirstNonBlankOnLine(position())) { moveToStartOfLine(); @@ -5200,10 +4731,8 @@ bool FakeVimHandler::Private::handleChangeCaseSubMode(const Input &input) return true; } -bool FakeVimHandler::Private::handleWindowSubMode(const Input &input) -{ - if (handleCount(input)) - return true; +bool FakeVimHandler::Private::handleWindowSubMode(const Input &input) { + if (handleCount(input)) return true; leaveVisualMode(); leaveCurrentMode(); @@ -5212,13 +4741,11 @@ bool FakeVimHandler::Private::handleWindowSubMode(const Input &input) return true; } -bool FakeVimHandler::Private::handleZSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleZSubMode(const Input &input) { bool handled = true; bool foldMaybeClosed = false; - if (input.isReturn() || input.is('t') - || input.is('-') || input.is('b') - || input.is('.') || input.is('z')) { + if (input.isReturn() || input.is('t') || input.is('-') || input.is('b') || input.is('.') || + input.is('z')) { // Cursor line to top/center/bottom of window. Qt::AlignmentFlag align; if (input.isReturn() || input.is('t')) @@ -5251,14 +4778,12 @@ bool FakeVimHandler::Private::handleZSubMode(const Input &input) } else { handled = false; } - if (foldMaybeClosed) - ensureCursorVisible(); + if (foldMaybeClosed) ensureCursorVisible(); g.submode = NoSubMode; return handled; } -bool FakeVimHandler::Private::handleCapitalZSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleCapitalZSubMode(const Input &input) { // Recognize ZZ and ZQ as aliases for ":x" and ":q!". bool handled = true; if (input.is('Z')) @@ -5271,26 +4796,22 @@ bool FakeVimHandler::Private::handleCapitalZSubMode(const Input &input) return handled; } -bool FakeVimHandler::Private::handleMacroRecordSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleMacroRecordSubMode(const Input &input) { g.submode = NoSubMode; return startRecording(input); } -bool FakeVimHandler::Private::handleMacroExecuteSubMode(const Input &input) -{ +bool FakeVimHandler::Private::handleMacroExecuteSubMode(const Input &input) { g.submode = NoSubMode; bool result = true; int repeat = count(); - while (result && --repeat >= 0) - result = executeRegister(input.asChar().unicode()); + while (result && --repeat >= 0) result = executeRegister(input.asChar().unicode()); return result; } -EventResult FakeVimHandler::Private::handleInsertOrReplaceMode(const Input &input) -{ +EventResult FakeVimHandler::Private::handleInsertOrReplaceMode(const Input &input) { if (position() < m_buffer->insertState.pos1 || position() > m_buffer->insertState.pos2) { commitInsertState(); invalidateInsertState(); @@ -5301,11 +4822,10 @@ EventResult FakeVimHandler::Private::handleInsertOrReplaceMode(const Input &inpu else handleReplaceMode(input); - if (!m_textedit && !m_plaintextedit) - return EventHandled; + if (!m_textedit && !m_plaintextedit) return EventHandled; - if (!isInsertMode() || m_buffer->breakEditBlock - || position() < m_buffer->insertState.pos1 || position() > m_buffer->insertState.pos2) { + if (!isInsertMode() || m_buffer->breakEditBlock || position() < m_buffer->insertState.pos1 || + position() > m_buffer->insertState.pos2) { commitInsertState(); invalidateInsertState(); breakEditBlock(); @@ -5316,8 +4836,7 @@ EventResult FakeVimHandler::Private::handleInsertOrReplaceMode(const Input &inpu return EventHandled; } -void FakeVimHandler::Private::handleReplaceMode(const Input &input) -{ +void FakeVimHandler::Private::handleReplaceMode(const Input &input) { if (input.isEscape()) { commitInsertState(); moveLeft(qMin(1, leftDist())); @@ -5350,8 +4869,7 @@ void FakeVimHandler::Private::handleReplaceMode(const Input &input) } } -void FakeVimHandler::Private::finishInsertMode() -{ +void FakeVimHandler::Private::finishInsertMode() { bool newLineAfter = m_buffer->insertState.newLineAfter; bool newLineBefore = m_buffer->insertState.newLineBefore; @@ -5380,13 +4898,12 @@ void FakeVimHandler::Private::finishInsertMode() const CursorPosition lastPosition = markGreaterPosition(); const bool change = m_visualBlockInsert == ChangeBlockInsertMode; const int insertColumn = (m_visualBlockInsert == InsertBlockInsertMode || change) - ? qMin(lastPosition.column, lastAnchor.column) - : qMax(lastPosition.column, lastAnchor.column) + 1; + ? qMin(lastPosition.column, lastAnchor.column) + : qMax(lastPosition.column, lastAnchor.column) + 1; CursorPosition pos(lastAnchor.line, insertColumn); - if (change) - pos.column = columnAt(m_buffer->insertState.pos1); + if (change) pos.column = columnAt(m_buffer->insertState.pos1); // Cursor position after block insert is on the first selected line, // last selected column for 's' command, otherwise first selected column. @@ -5433,8 +4950,7 @@ void FakeVimHandler::Private::finishInsertMode() enterCommandMode(); } -void FakeVimHandler::Private::handleInsertMode(const Input &input) -{ +void FakeVimHandler::Private::handleInsertMode(const Input &input) { if (input.isEscape()) { if (g.submode == CtrlRSubMode || g.submode == CtrlVSubMode) { g.submode = NoSubMode; @@ -5480,8 +4996,7 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input) } else { bool ok; int current = input.toInt(&ok, m_ctrlVBase); - if (ok) - m_ctrlVAccumulator = m_ctrlVAccumulator * m_ctrlVBase + current; + if (ok) m_ctrlVAccumulator = m_ctrlVAccumulator * m_ctrlVBase + current; --m_ctrlVLength; if (m_ctrlVLength == 0 || !ok) { QString s; @@ -5496,8 +5011,7 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input) g.subsubmode = NoSubSubMode; // Try again without Ctrl-V interpretation. - if (!ok) - handleInsertMode(input); + if (!ok) handleInsertMode(input); } } } else if (input.isControl('o')) { @@ -5514,8 +5028,7 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input) const int blockNumber = m_cursor.blockNumber(); const int endPos = position(); moveToNextWordStart(1, false, false); - if (blockNumber != m_cursor.blockNumber()) - moveToEndOfLine(); + if (blockNumber != m_cursor.blockNumber()) moveToEndOfLine(); const int beginPos = position(); Range range(beginPos, endPos, RangeCharMode); removeText(range); @@ -5523,8 +5036,7 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input) const int blockNumber = m_cursor.blockNumber(); const int endPos = position(); moveToStartOfLine(); - if (blockNumber != m_cursor.blockNumber()) - moveToEndOfLine(); + if (blockNumber != m_cursor.blockNumber()) moveToEndOfLine(); const int beginPos = position(); Range range(beginPos, endPos, RangeCharMode); removeText(range); @@ -5560,15 +5072,14 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input) // pass C-h as backspace, too if (!handleInsertInEditor(Input(Qt::Key_Backspace, Qt::NoModifier))) { joinPreviousEditBlock(); - if (!m_buffer->lastInsertion.isEmpty() - || s.backspace.value().contains("start") - || s.backspace.value().contains("2")) { + if (!m_buffer->lastInsertion.isEmpty() || s.backspace.value().contains("start") || + s.backspace.value().contains("2")) { const int line = cursorLine() + 1; const Column col = cursorColumn(); QString data = lineContents(line); const Column ind = indentation(data); - if (col.logical <= ind.logical && col.logical - && startsWithWhitespace(data, col.physical)) { + if (col.logical <= ind.logical && col.logical && + startsWithWhitespace(data, col.physical)) { const int ts = s.tabStop.value(); const int newl = col.logical - 1 - (col.logical - 1) % ts; const QString prefix = tabExpand(newl); @@ -5616,11 +5127,11 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input) if (text.at(i) == ' ') ++amount; else if (text.at(i) == '\t') - amount += tab; // FIXME: take position into consideration + amount += tab; // FIXME: take position into consideration else break; } - removeText(Range(pos, pos+i)); + removeText(Range(pos, pos + i)); } else if (input.isControl('p') || input.isControl('n')) { QTextCursor tc = m_cursor; moveToNextWordStart(1, false, false); @@ -5631,27 +5142,23 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input) // Insert text from clipboard. QClipboard *clipboard = QApplication::clipboard(); const QMimeData *data = clipboard->mimeData(); - if (data && data->hasText()) - insertInInsertMode(data->text()); + if (data && data->hasText()) insertInInsertMode(data->text()); } else { m_buffer->insertState.insertingSpaces = input.isKey(Key_Space); if (!handleInsertInEditor(input)) { const QString toInsert = input.text(); - if (toInsert.isEmpty()) - return; + if (toInsert.isEmpty()) return; insertInInsertMode(toInsert); } m_buffer->insertState.insertingSpaces = false; } } -void FakeVimHandler::Private::insertInInsertMode(const QString &text) -{ +void FakeVimHandler::Private::insertInInsertMode(const QString &text) { joinPreviousEditBlock(); insertText(text); if (s.smartIndent.value() && isElectricCharacter(text.at(0))) { - const QString leftText = block().text() - .left(position() - 1 - block().position()); + const QString leftText = block().text().left(position() - 1 - block().position()); if (leftText.simplified().isEmpty()) { Range range(position(), position(), g.rangemode); indentText(range, text.at(0)); @@ -5662,8 +5169,7 @@ void FakeVimHandler::Private::insertInInsertMode(const QString &text) g.submode = NoSubMode; } -bool FakeVimHandler::Private::startRecording(const Input &input) -{ +bool FakeVimHandler::Private::startRecording(const Input &input) { QChar reg = input.asChar(); if (reg == '"' || reg.isLetterOrNumber()) { g.currentRegister = reg.unicode(); @@ -5675,14 +5181,11 @@ bool FakeVimHandler::Private::startRecording(const Input &input) return false; } -void FakeVimHandler::Private::record(const Input &input) -{ - if (g.isRecording) - g.recorded.append(input.toString()); +void FakeVimHandler::Private::record(const Input &input) { + if (g.isRecording) g.recorded.append(input.toString()); } -void FakeVimHandler::Private::stopRecording() -{ +void FakeVimHandler::Private::stopRecording() { // Remove q from end (stop recording command). g.isRecording = false; g.recorded.chop(1); @@ -5691,8 +5194,7 @@ void FakeVimHandler::Private::stopRecording() g.recorded.clear(); } -void FakeVimHandler::Private::handleAs(const QString &command) -{ +void FakeVimHandler::Private::handleAs(const QString &command) { QString cmd = QStringLiteral("\"%1").arg(QChar(m_register)); if (command.contains("%1")) @@ -5706,8 +5208,7 @@ void FakeVimHandler::Private::handleAs(const QString &command) endEditBlock(); } -bool FakeVimHandler::Private::executeRegister(int reg) -{ +bool FakeVimHandler::Private::executeRegister(int reg) { QChar regChar(reg); // TODO: Prompt for an expression to execute if register is '='. @@ -5727,11 +5228,9 @@ bool FakeVimHandler::Private::executeRegister(int reg) return true; } -EventResult FakeVimHandler::Private::handleExMode(const Input &input) -{ +EventResult FakeVimHandler::Private::handleExMode(const Input &input) { // handle C-R, C-R C-W, C-R {register} - if (handleCommandBufferPaste(input)) - return EventHandled; + if (handleCommandBufferPaste(input)) return EventHandled; if (input.isEscape()) { g.commandBuffer.clear(); @@ -5768,13 +5267,11 @@ EventResult FakeVimHandler::Private::handleExMode(const Input &input) return EventHandled; } -EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input) -{ +EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input) { EventResult handled = EventHandled; // handle C-R, C-R C-W, C-R {register} - if (handleCommandBufferPaste(input)) - return handled; + if (handleCommandBufferPaste(input)) return handled; if (input.isEscape()) { g.currentMessage.clear(); @@ -5799,15 +5296,14 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input) if (finishSearch()) { if (g.submode != NoSubMode) finishMovement(g.searchBuffer.prompt() + g.lastSearch + '\n'); - if (g.currentMessage.isEmpty()) - showMessage(MessageCommand, g.searchBuffer.display()); + if (g.currentMessage.isEmpty()) showMessage(MessageCommand, g.searchBuffer.display()); } else { - handled = EventCancelled; // Not found so cancel mapping if any. + handled = EventCancelled; // Not found so cancel mapping if any. } } else if (input.isKey(Key_Tab)) { g.searchBuffer.insertChar(QChar(9)); } else if (!g.searchBuffer.handleInput(input)) { - //qDebug() << "IGNORED IN SEARCH MODE: " << input.key() << input.text(); + // qDebug() << "IGNORED IN SEARCH MODE: " << input.key() << input.text(); return EventUnhandled; } @@ -5822,21 +5318,19 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input) } // This uses 0 based line counting (hidden lines included). -int FakeVimHandler::Private::parseLineAddress(QString *cmd) -{ - //qDebug() << "CMD: " << cmd; - if (cmd->isEmpty()) - return -1; +int FakeVimHandler::Private::parseLineAddress(QString *cmd) { + // qDebug() << "CMD: " << cmd; + if (cmd->isEmpty()) return -1; int result = -1; QChar c = cmd->at(0); - if (c == '.') { // current line + if (c == '.') { // current line result = cursorBlockNumber(); cmd->remove(0, 1); - } else if (c == '$') { // last line + } else if (c == '$') { // last line result = document()->blockCount() - 1; cmd->remove(0, 1); - } else if (c == '\'') { // mark + } else if (c == '\'') { // mark cmd->remove(0, 1); if (cmd->isEmpty()) { showMessage(MessageError, msgMarkNotSet(QString())); @@ -5850,18 +5344,17 @@ int FakeVimHandler::Private::parseLineAddress(QString *cmd) } cmd->remove(0, 1); result = m.position(document()).line; - } else if (c.isDigit()) { // line with given number + } else if (c.isDigit()) { // line with given number result = 0; - } else if (c == '-' || c == '+') { // add or subtract from current line number + } else if (c == '-' || c == '+') { // add or subtract from current line number result = cursorBlockNumber(); - } else if (c == '/' || c == '?' - || (c == '\\' && cmd->size() > 1 && QStringLiteral("/?&").contains(cmd->at(1)))) { + } else if (c == '/' || c == '?' || + (c == '\\' && cmd->size() > 1 && QStringLiteral("/?&").contains(cmd->at(1)))) { // search for expression SearchData sd; if (c == '/' || c == '?') { const int end = findUnescaped(c, *cmd, 1); - if (end == -1) - return -1; + if (end == -1) return -1; sd.needle = cmd->mid(1, end - 1); cmd->remove(0, end + 1); } else { @@ -5874,8 +5367,7 @@ int FakeVimHandler::Private::parseLineAddress(QString *cmd) const int pos = b.position() + (sd.forward ? b.length() - 1 : 0); QTextCursor tc = search(sd, pos, 1, true); g.lastSearch = sd.needle; - if (tc.isNull()) - return -1; + if (tc.isNull()) return -1; result = tc.block().blockNumber(); } else { return cursorBlockNumber(); @@ -5888,8 +5380,7 @@ int FakeVimHandler::Private::parseLineAddress(QString *cmd) for (; i < cmd->size(); ++i) { c = cmd->at(i); if (c == '-' || c == '+') { - if (n != 0) - result = result + (add ? n - 1 : -(n - 1)); + if (n != 0) result = result + (add ? n - 1 : -(n - 1)); add = c == '+'; result = result + (add ? 1 : -1); n = 0; @@ -5899,28 +5390,23 @@ int FakeVimHandler::Private::parseLineAddress(QString *cmd) break; } } - if (n != 0) - result = result + (add ? n - 1 : -(n - 1)); + if (n != 0) result = result + (add ? n - 1 : -(n - 1)); *cmd = cmd->mid(i).trimmed(); return result; } -void FakeVimHandler::Private::setCurrentRange(const Range &range) -{ +void FakeVimHandler::Private::setCurrentRange(const Range &range) { setAnchorAndPosition(range.beginPos, range.endPos); g.rangemode = range.rangemode; } -bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd) -{ +bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd) { *cmd = ExCommand(); - if (line->isEmpty()) - return false; + if (line->isEmpty()) return false; // parse range first - if (!parseLineRange(line, cmd)) - return false; + if (!parseLineRange(line, cmd)) return false; // get first command from command line QChar close; @@ -5929,7 +5415,7 @@ bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd) for (; i < line->size(); ++i) { const QChar &c = line->at(i); if (c == '\\') { - ++i; // skip escaped character + ++i; // skip escaped character } else if (close.isNull()) { if (c == '|') { // split on | @@ -5958,8 +5444,7 @@ bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd) // '!' at the end of command cmd->hasBang = cmd->args.startsWith('!'); - if (cmd->hasBang) - cmd->args = cmd->args.mid(1).trimmed(); + if (cmd->hasBang) cmd->args = cmd->args.mid(1).trimmed(); } // remove the first command from command line @@ -5968,8 +5453,7 @@ bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd) return true; } -bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd) -{ +bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd) { // remove leading colons and spaces line->remove(QRegularExpression("^\\s*(:+\\s*)*")); @@ -5980,8 +5464,7 @@ bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd) } // FIXME: that seems to be different for %w and %s - if (line->startsWith('%')) - line->replace(0, 1, "1,$"); + if (line->startsWith('%')) line->replace(0, 1, "1,$"); int beginLine = parseLineAddress(line); int endLine; @@ -5991,8 +5474,7 @@ bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd) } else { endLine = beginLine; } - if (beginLine == -1 || endLine == -1) - return false; + if (beginLine == -1 || endLine == -1) return false; const int beginPos = firstPositionInLine(qMin(beginLine, endLine) + 1, false); const int endPos = lastPositionInLine(qMax(beginLine, endLine) + 1, false); @@ -6002,8 +5484,7 @@ bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd) return true; } -void FakeVimHandler::Private::parseRangeCount(const QString &line, Range *range) const -{ +void FakeVimHandler::Private::parseRangeCount(const QString &line, Range *range) const { bool ok; const int count = qAbs(line.trimmed().toInt(&ok)); if (ok) { @@ -6015,16 +5496,12 @@ void FakeVimHandler::Private::parseRangeCount(const QString &line, Range *range) } // use handleExCommand for invoking commands that might move the cursor -void FakeVimHandler::Private::handleCommand(const QString &cmd) -{ - handleExCommand(cmd); -} +void FakeVimHandler::Private::handleCommand(const QString &cmd) { handleExCommand(cmd); } -bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) { // :substitute - if (!cmd.matches("s", "substitute") - && !(cmd.cmd.isEmpty() && !cmd.args.isEmpty() && QStringLiteral("&~").contains(cmd.args[0]))) { + if (!cmd.matches("s", "substitute") && + !(cmd.cmd.isEmpty() && !cmd.args.isEmpty() && QStringLiteral("&~").contains(cmd.args[0]))) { return false; } @@ -6042,8 +5519,7 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) g.lastSubstituteFlags += line.mid(2); else g.lastSubstituteFlags = line.mid(1); - if (line[0] == '~') - g.lastSubstitutePattern = g.lastSearch; + if (line[0] == '~') g.lastSubstitutePattern = g.lastSearch; } else { if (line.isEmpty()) { g.lastSubstituteFlags.clear(); @@ -6051,11 +5527,9 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) // we have /{pattern}/{string}/[flags] now const QChar separator = line.at(0); int pos1 = findUnescaped(separator, line, 1); - if (pos1 == -1) - return false; + if (pos1 == -1) return false; int pos2 = findUnescaped(separator, line, pos1 + 1); - if (pos2 == -1) - pos2 = line.size(); + if (pos2 == -1) pos2 = line.size(); g.lastSubstitutePattern = line.mid(1, pos1 - 1); g.lastSubstituteReplacement = line.mid(pos1 + 1, pos2 - pos1 - 1); @@ -6066,8 +5540,7 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) count = qMax(1, count); QString needle = g.lastSubstitutePattern; - if (g.lastSubstituteFlags.contains('i')) - needle.prepend("\\c"); + if (g.lastSubstituteFlags.contains('i')) needle.prepend("\\c"); const QRegularExpression pattern = vimPatternToQtPattern_QRegularExpression(needle); @@ -6076,8 +5549,8 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) const bool global = g.lastSubstituteFlags.contains('g'); for (int a = 0; a != count; ++a) { for (QTextBlock block = blockAt(cmd.range.endPos); - block.isValid() && block.position() + block.length() > cmd.range.beginPos; - block = block.previous()) { + block.isValid() && block.position() + block.length() > cmd.range.beginPos; + block = block.previous()) { QString text = block.text(); if (substituteText(&text, pattern, g.lastSubstituteReplacement, global)) { firstBlock = block; @@ -6109,25 +5582,21 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExTabNextCommand(const ExCommand &cmd) -{ - if (!cmd.matches("tabn", "tabnext")) - return false; +bool FakeVimHandler::Private::handleExTabNextCommand(const ExCommand &cmd) { + if (!cmd.matches("tabn", "tabnext")) return false; q->tabNextRequested(); return true; } -bool FakeVimHandler::Private::handleExTabPreviousCommand(const ExCommand &cmd) -{ - if (!cmd.matches("tabp", "tabprevious")) - return false; +bool FakeVimHandler::Private::handleExTabPreviousCommand(const ExCommand &cmd) { + if (!cmd.matches("tabp", "tabprevious")) return false; q->tabPreviousRequested(); return true; } -bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map +bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map { QByteArray modes; enum Type { Map, Noremap, Unmap } type; @@ -6135,38 +5604,101 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map QByteArray cmd = cmd0.cmd.toLatin1(); // Strange formatting. But everything else is even uglier. - if (cmd == "map") { modes = "nvo"; type = Map; } else - if (cmd == "nm" || cmd == "nmap") { modes = "n"; type = Map; } else - if (cmd == "vm" || cmd == "vmap") { modes = "v"; type = Map; } else - if (cmd == "xm" || cmd == "xmap") { modes = "x"; type = Map; } else - if (cmd == "smap") { modes = "s"; type = Map; } else - if (cmd == "omap") { modes = "o"; type = Map; } else - if (cmd == "map!") { modes = "ic"; type = Map; } else - if (cmd == "im" || cmd == "imap") { modes = "i"; type = Map; } else - if (cmd == "lm" || cmd == "lmap") { modes = "l"; type = Map; } else - if (cmd == "cm" || cmd == "cmap") { modes = "c"; type = Map; } else + if (cmd == "map") { + modes = "nvo"; + type = Map; + } else if (cmd == "nm" || cmd == "nmap") { + modes = "n"; + type = Map; + } else if (cmd == "vm" || cmd == "vmap") { + modes = "v"; + type = Map; + } else if (cmd == "xm" || cmd == "xmap") { + modes = "x"; + type = Map; + } else if (cmd == "smap") { + modes = "s"; + type = Map; + } else if (cmd == "omap") { + modes = "o"; + type = Map; + } else if (cmd == "map!") { + modes = "ic"; + type = Map; + } else if (cmd == "im" || cmd == "imap") { + modes = "i"; + type = Map; + } else if (cmd == "lm" || cmd == "lmap") { + modes = "l"; + type = Map; + } else if (cmd == "cm" || cmd == "cmap") { + modes = "c"; + type = Map; + } else - if (cmd == "no" || cmd == "noremap") { modes = "nvo"; type = Noremap; } else - if (cmd == "nn" || cmd == "nnoremap") { modes = "n"; type = Noremap; } else - if (cmd == "vn" || cmd == "vnoremap") { modes = "v"; type = Noremap; } else - if (cmd == "xn" || cmd == "xnoremap") { modes = "x"; type = Noremap; } else - if (cmd == "snor" || cmd == "snoremap") { modes = "s"; type = Noremap; } else - if (cmd == "ono" || cmd == "onoremap") { modes = "o"; type = Noremap; } else - if (cmd == "no!" || cmd == "noremap!") { modes = "ic"; type = Noremap; } else - if (cmd == "ino" || cmd == "inoremap") { modes = "i"; type = Noremap; } else - if (cmd == "ln" || cmd == "lnoremap") { modes = "l"; type = Noremap; } else - if (cmd == "cno" || cmd == "cnoremap") { modes = "c"; type = Noremap; } else + if (cmd == "no" || cmd == "noremap") { + modes = "nvo"; + type = Noremap; + } else if (cmd == "nn" || cmd == "nnoremap") { + modes = "n"; + type = Noremap; + } else if (cmd == "vn" || cmd == "vnoremap") { + modes = "v"; + type = Noremap; + } else if (cmd == "xn" || cmd == "xnoremap") { + modes = "x"; + type = Noremap; + } else if (cmd == "snor" || cmd == "snoremap") { + modes = "s"; + type = Noremap; + } else if (cmd == "ono" || cmd == "onoremap") { + modes = "o"; + type = Noremap; + } else if (cmd == "no!" || cmd == "noremap!") { + modes = "ic"; + type = Noremap; + } else if (cmd == "ino" || cmd == "inoremap") { + modes = "i"; + type = Noremap; + } else if (cmd == "ln" || cmd == "lnoremap") { + modes = "l"; + type = Noremap; + } else if (cmd == "cno" || cmd == "cnoremap") { + modes = "c"; + type = Noremap; + } else - if (cmd == "unm" || cmd == "unmap") { modes = "nvo"; type = Unmap; } else - if (cmd == "nun" || cmd == "nunmap") { modes = "n"; type = Unmap; } else - if (cmd == "vu" || cmd == "vunmap") { modes = "v"; type = Unmap; } else - if (cmd == "xu" || cmd == "xunmap") { modes = "x"; type = Unmap; } else - if (cmd == "sunm" || cmd == "sunmap") { modes = "s"; type = Unmap; } else - if (cmd == "ou" || cmd == "ounmap") { modes = "o"; type = Unmap; } else - if (cmd == "unm!" || cmd == "unmap!") { modes = "ic"; type = Unmap; } else - if (cmd == "iu" || cmd == "iunmap") { modes = "i"; type = Unmap; } else - if (cmd == "lu" || cmd == "lunmap") { modes = "l"; type = Unmap; } else - if (cmd == "cu" || cmd == "cunmap") { modes = "c"; type = Unmap; } + if (cmd == "unm" || cmd == "unmap") { + modes = "nvo"; + type = Unmap; + } else if (cmd == "nun" || cmd == "nunmap") { + modes = "n"; + type = Unmap; + } else if (cmd == "vu" || cmd == "vunmap") { + modes = "v"; + type = Unmap; + } else if (cmd == "xu" || cmd == "xunmap") { + modes = "x"; + type = Unmap; + } else if (cmd == "sunm" || cmd == "sunmap") { + modes = "s"; + type = Unmap; + } else if (cmd == "ou" || cmd == "ounmap") { + modes = "o"; + type = Unmap; + } else if (cmd == "unm!" || cmd == "unmap!") { + modes = "ic"; + type = Unmap; + } else if (cmd == "iu" || cmd == "iunmap") { + modes = "i"; + type = Unmap; + } else if (cmd == "lu" || cmd == "lunmap") { + modes = "l"; + type = Unmap; + } else if (cmd == "cu" || cmd == "cunmap") { + modes = "c"; + type = Unmap; + } else return false; @@ -6198,33 +5730,30 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map const QString rhs = args.section(QRegularExpression("\\s+"), 1); if ((rhs.isNull() && type != Unmap) || (!rhs.isNull() && type == Unmap)) { // FIXME: Dump mappings here. - //qDebug() << g.mappings; + // qDebug() << g.mappings; return true; } Inputs key(lhs); - //qDebug() << "MAPPING: " << modes << lhs << rhs; + // qDebug() << "MAPPING: " << modes << lhs << rhs; switch (type) { case Unmap: - foreach (char c, modes) - MappingsIterator(&g.mappings, c, key).remove(); + foreach (char c, modes) MappingsIterator(&g.mappings, c, key).remove(); break; - case Map: Q_FALLTHROUGH(); + case Map: + Q_FALLTHROUGH(); case Noremap: { Inputs inputs(rhs, type == Noremap, silent); - foreach (char c, modes) - MappingsIterator(&g.mappings, c).setInputs(key, inputs, unique); + foreach (char c, modes) MappingsIterator(&g.mappings, c).setInputs(key, inputs, unique); break; } } return true; } -bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd) { // :his[tory] - if (!cmd.matches("his", "history")) - return false; + if (!cmd.matches("his", "history")) return false; if (cmd.args.isEmpty()) { QString info; @@ -6242,23 +5771,20 @@ bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExRegisterCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExRegisterCommand(const ExCommand &cmd) { // :reg[isters] and :di[splay] - if (!cmd.matches("reg", "registers") && !cmd.matches("di", "display")) - return false; + if (!cmd.matches("reg", "registers") && !cmd.matches("di", "display")) return false; QByteArray regs = cmd.args.toLatin1(); if (regs.isEmpty()) { regs = "\"0123456789"; for (auto it = g.registers.cbegin(), end = g.registers.cend(); it != end; ++it) { - if (it.key() > '9') - regs += char(it.key()); + if (it.key() > '9') regs += char(it.key()); } } QString info; info += "--- Registers ---\n"; - const auto& registers = regs; + const auto ®isters = regs; for (char reg : registers) { QString value = quoteUnprintable(registerContents(reg)); info += QStringLiteral("\"%1 %2\n").arg(reg).arg(value); @@ -6268,11 +5794,9 @@ bool FakeVimHandler::Private::handleExRegisterCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) { // :se[t] - if (!cmd.matches("se", "set")) - return false; + if (!cmd.matches("se", "set")) return false; clearMessage(); @@ -6280,19 +5804,16 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) // Non-boolean config to set. int p = cmd.args.indexOf('='); QString error = s.trySetValue(cmd.args.left(p), cmd.args.mid(p + 1)); - if (!error.isEmpty()) - showMessage(MessageError, error); + if (!error.isEmpty()) showMessage(MessageError, error); } else { QString optionName = cmd.args; bool toggleOption = optionName.endsWith('!'); bool printOption = !toggleOption && optionName.endsWith('?'); - if (printOption || toggleOption) - optionName.chop(1); + if (printOption || toggleOption) optionName.chop(1); bool negateOption = optionName.startsWith("no"); - if (negateOption) - optionName.remove(0, 2); + if (negateOption) optionName.remove(0, 2); FvBaseAspect *act = s.item(optionName); if (!act) { @@ -6300,8 +5821,8 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) } else if (act->defaultValue().type() == QVariant::Bool) { bool oldValue = act->value().toBool(); if (printOption) { - showMessage(MessageInfo, QLatin1String(oldValue ? "" : "no") - + act->settingsKey().toLower()); + showMessage(MessageInfo, + QLatin1String(oldValue ? "" : "no") + act->settingsKey().toLower()); } else if (toggleOption || negateOption == oldValue) { act->setValue(!oldValue); } @@ -6310,8 +5831,7 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) } else if (toggleOption) { showMessage(MessageError, Tr::tr("Trailing characters:") + ' ' + cmd.args); } else { - showMessage(MessageInfo, act->settingsKey().toLower() + "=" - + act->value().toString()); + showMessage(MessageInfo, act->settingsKey().toLower() + "=" + act->value().toString()); } } updateEditor(); @@ -6319,23 +5839,19 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExNormalCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExNormalCommand(const ExCommand &cmd) { // :norm[al] - if (!cmd.matches("norm", "normal")) - return false; - //qDebug() << "REPLAY NORMAL: " << quoteUnprintable(reNormal.cap(3)); + if (!cmd.matches("norm", "normal")) return false; + // qDebug() << "REPLAY NORMAL: " << quoteUnprintable(reNormal.cap(3)); replay(cmd.args); return true; } -bool FakeVimHandler::Private::handleExYankDeleteCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExYankDeleteCommand(const ExCommand &cmd) { // :[range]d[elete] [x] [count] // :[range]y[ank] [x] [count] const bool remove = cmd.matches("d", "delete"); - if (!remove && !cmd.matches("y", "yank")) - return false; + if (!remove && !cmd.matches("y", "yank")) return false; // get register from arguments const bool hasRegisterArg = !cmd.args.isEmpty() && !cmd.args.at(0).isDigit(); @@ -6358,11 +5874,9 @@ bool FakeVimHandler::Private::handleExYankDeleteCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExChangeCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExChangeCommand(const ExCommand &cmd) { // :[range]c[hange] - if (!cmd.matches("c", "change")) - return false; + if (!cmd.matches("c", "change")) return false; Range range = cmd.range; range.rangemode = RangeLineModeExclusive; @@ -6376,11 +5890,9 @@ bool FakeVimHandler::Private::handleExChangeCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExMoveCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExMoveCommand(const ExCommand &cmd) { // :[range]m[ove] {address} - if (!cmd.matches("m", "move")) - return false; + if (!cmd.matches("m", "move")) return false; QString lineCode = cmd.args; @@ -6406,8 +5918,7 @@ bool FakeVimHandler::Private::handleExMoveCommand(const ExCommand &cmd) removeText(currentRange()); const bool insertAtEnd = targetLine == document()->blockCount(); - if (targetLine >= startLine) - targetLine -= lines; + if (targetLine >= startLine) targetLine -= lines; QTextBlock block = document()->findBlockByNumber(insertAtEnd ? targetLine : targetLine + 1); setPosition(block.position()); setAnchor(); @@ -6419,10 +5930,8 @@ bool FakeVimHandler::Private::handleExMoveCommand(const ExCommand &cmd) } insertText(text); - if (!insertAtEnd) - moveUp(1); - if (s.startOfLine.value()) - moveToFirstNonBlankOnLine(); + if (!insertAtEnd) moveUp(1); + if (s.startOfLine.value()) moveToFirstNonBlankOnLine(); if (lastAnchor.line >= startLine && lastAnchor.line <= endLine) lastAnchor.line += targetLine - startLine + 1; @@ -6431,18 +5940,15 @@ bool FakeVimHandler::Private::handleExMoveCommand(const ExCommand &cmd) setMark('<', lastAnchor); setMark('>', lastPosition); - if (lines > 2) - showMessage(MessageInfo, Tr::tr("%n lines moved.", nullptr, lines)); + if (lines > 2) showMessage(MessageInfo, Tr::tr("%n lines moved.", nullptr, lines)); return true; } -bool FakeVimHandler::Private::handleExJoinCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExJoinCommand(const ExCommand &cmd) { // :[range]j[oin][!] [count] // FIXME: Argument [count] can follow immediately. - if (!cmd.matches("j", "join")) - return false; + if (!cmd.matches("j", "join")) return false; // get [count] from arguments bool ok; @@ -6466,39 +5972,32 @@ bool FakeVimHandler::Private::handleExJoinCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) { // Note: The cmd.args.isEmpty() case is handled by handleExPluginCommand. // :w, :x, :wq, ... - //static QRegularExpression reWrite("^[wx]q?a?!?( (.*))?$"); - if (cmd.cmd != "w" && cmd.cmd != "x" && cmd.cmd != "wq") - return false; + // static QRegularExpression reWrite("^[wx]q?a?!?( (.*))?$"); + if (cmd.cmd != "w" && cmd.cmd != "x" && cmd.cmd != "wq") return false; int beginLine = lineForPosition(cmd.range.beginPos); int endLine = lineForPosition(cmd.range.endPos); const bool noArgs = (beginLine == -1); - if (beginLine == -1) - beginLine = 0; - if (endLine == -1) - endLine = linesInDocument(); - //qDebug() << "LINES: " << beginLine << endLine; - //QString prefix = cmd.args; + if (beginLine == -1) beginLine = 0; + if (endLine == -1) endLine = linesInDocument(); + // qDebug() << "LINES: " << beginLine << endLine; + // QString prefix = cmd.args; const bool forced = cmd.hasBang; - //const bool quit = prefix.contains('q') || prefix.contains('x'); - //const bool quitAll = quit && prefix.contains('a'); + // const bool quit = prefix.contains('q') || prefix.contains('x'); + // const bool quitAll = quit && prefix.contains('a'); QString fileName = replaceTildeWithHome(cmd.args); - if (fileName.isEmpty()) - fileName = m_currentFileName; + if (fileName.isEmpty()) fileName = m_currentFileName; QFile file1(fileName); const bool exists = file1.exists(); if (exists && !forced && !noArgs) { - showMessage(MessageError, Tr::tr - ("File \"%1\" exists (add ! to override)").arg(fileName)); + showMessage(MessageError, Tr::tr("File \"%1\" exists (add ! to override)").arg(fileName)); } else if (file1.open(QIODevice::ReadWrite)) { // Nobody cared, so act ourselves. file1.close(); - Range range(firstPositionInLine(beginLine), - firstPositionInLine(endLine), RangeLineMode); + Range range(firstPositionInLine(beginLine), firstPositionInLine(endLine), RangeLineMode); QString contents = selectText(range); QFile::remove(fileName); QFile file2(fileName); @@ -6506,32 +6005,30 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) QTextStream ts(&file2); ts << contents; } else { - showMessage(MessageError, Tr::tr - ("Cannot open file \"%1\" for writing").arg(fileName)); + showMessage(MessageError, Tr::tr("Cannot open file \"%1\" for writing").arg(fileName)); } // Check result by reading back. QFile file3(fileName); file3.open(QIODevice::ReadOnly); QByteArray ba = file3.readAll(); showMessage(MessageInfo, Tr::tr("\"%1\" %2 %3L, %4C written.") - .arg(fileName).arg(exists ? QStringLiteral(" ") : Tr::tr(" [New] ")) - .arg(ba.count('\n')).arg(ba.size())); - //if (quitAll) - // passUnknownExCommand(forced ? "qa!" : "qa"); - //else if (quit) - // passUnknownExCommand(forced ? "q!" : "q"); + .arg(fileName) + .arg(exists ? QStringLiteral(" ") : Tr::tr(" [New] ")) + .arg(ba.count('\n')) + .arg(ba.size())); + // if (quitAll) + // passUnknownExCommand(forced ? "qa!" : "qa"); + // else if (quit) + // passUnknownExCommand(forced ? "q!" : "q"); } else { - showMessage(MessageError, Tr::tr - ("Cannot open file \"%1\" for reading").arg(fileName)); + showMessage(MessageError, Tr::tr("Cannot open file \"%1\" for reading").arg(fileName)); } return true; } -bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd) { // :r[ead] - if (!cmd.matches("r", "read")) - return false; + if (!cmd.matches("r", "read")) return false; beginEditBlock(); @@ -6550,16 +6047,16 @@ bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd) endEditBlock(); - showMessage(MessageInfo, Tr::tr("\"%1\" %2L, %3C") - .arg(m_currentFileName).arg(data.count('\n')).arg(data.size())); + showMessage( + MessageInfo, + Tr::tr("\"%1\" %2L, %3C").arg(m_currentFileName).arg(data.count('\n')).arg(data.size())); return true; } -bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! +bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! { - if (!cmd.cmd.isEmpty() || !cmd.hasBang) - return false; + if (!cmd.cmd.isEmpty() || !cmd.hasBang) return false; bool replaceText = cmd.range.isValid(); const QString command = QString(cmd.cmd.mid(1) + ' ' + cmd.args).trimmed(); @@ -6576,9 +6073,8 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! setPosition(targetPosition); endEditBlock(); leaveVisualMode(); - //qDebug() << "FILTER: " << command; - showMessage(MessageInfo, Tr::tr("%n lines filtered.", nullptr, - input.count('\n'))); + // qDebug() << "FILTER: " << command; + showMessage(MessageInfo, Tr::tr("%n lines filtered.", nullptr, input.count('\n'))); } else if (!result.isEmpty()) { q->extraInformationChanged(result); } @@ -6586,8 +6082,7 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! return true; } -bool FakeVimHandler::Private::handleExShiftCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExShiftCommand(const ExCommand &cmd) { // :[range]{<|>}* [count] if (!cmd.cmd.isEmpty() || (!cmd.args.startsWith('<') && !cmd.args.startsWith('>'))) return false; @@ -6620,12 +6115,10 @@ bool FakeVimHandler::Private::handleExShiftCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExSortCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExSortCommand(const ExCommand &cmd) { // :[range]sor[t][!] [b][f][i][n][o][r][u][x] [/{pattern}/] // FIXME: Only the ! for reverse is implemented. - if (!cmd.matches("sor", "sort")) - return false; + if (!cmd.matches("sor", "sort")) return false; // Force operation on full lines, and full document if only // one line (the current one...) is specified @@ -6635,17 +6128,15 @@ bool FakeVimHandler::Private::handleExSortCommand(const ExCommand &cmd) beginLine = 0; endLine = lineForPosition(lastPositionInDocument()); } - Range range(firstPositionInLine(beginLine), - firstPositionInLine(endLine), RangeLineMode); + Range range(firstPositionInLine(beginLine), firstPositionInLine(endLine), RangeLineMode); QString input = selectText(range); - if (input.endsWith('\n')) // It should always... + if (input.endsWith('\n')) // It should always... input.chop(1); QStringList lines = input.split('\n'); lines.sort(); - if (cmd.hasBang) - std::reverse(lines.begin(), lines.end()); + if (cmd.hasBang) std::reverse(lines.begin(), lines.end()); QString res = lines.join('\n') + '\n'; replaceText(range, res); @@ -6653,35 +6144,29 @@ bool FakeVimHandler::Private::handleExSortCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExNohlsearchCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExNohlsearchCommand(const ExCommand &cmd) { // :noh, :nohl, ..., :nohlsearch - if (cmd.cmd.size() < 3 || !QStringLiteral("nohlsearch").startsWith(cmd.cmd)) - return false; + if (cmd.cmd.size() < 3 || !QStringLiteral("nohlsearch").startsWith(cmd.cmd)) return false; g.highlightsCleared = true; updateHighlights(); return true; } -bool FakeVimHandler::Private::handleExUndoRedoCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExUndoRedoCommand(const ExCommand &cmd) { // :undo // :redo bool undo = (cmd.cmd == "u" || cmd.cmd == "un" || cmd.cmd == "undo"); - if (!undo && cmd.cmd != "red" && cmd.cmd != "redo") - return false; + if (!undo && cmd.cmd != "red" && cmd.cmd != "redo") return false; undoRedo(undo); return true; } -bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd) { // :{address} - if (!cmd.cmd.isEmpty() || !cmd.args.isEmpty()) - return false; + if (!cmd.cmd.isEmpty() || !cmd.args.isEmpty()) return false; const int beginLine = lineForPosition(cmd.range.endPos); setPosition(firstPositionInLine(beginLine)); @@ -6689,11 +6174,9 @@ bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) { // :source - if (cmd.cmd != "so" && cmd.cmd != "source") - return false; + if (cmd.cmd != "so" && cmd.cmd != "source") return false; QString fileName = replaceTildeWithHome(cmd.args); QFile file(fileName); @@ -6709,8 +6192,7 @@ bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) // remove comment int i = nextline.lastIndexOf('"'); - if (i != -1) - nextline = nextline.remove(i, nextline.size() - i); + if (i != -1) nextline = nextline.remove(i, nextline.size() - i); nextline = nextline.trimmed(); @@ -6721,17 +6203,16 @@ bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) } if (line.startsWith("function")) { - //qDebug() << "IGNORING FUNCTION" << line; + // qDebug() << "IGNORING FUNCTION" << line; inFunction = true; } else if (inFunction && line.startsWith("endfunction")) { inFunction = false; } else if (!line.isEmpty() && !inFunction) { - //qDebug() << "EXECUTING: " << line; + // qDebug() << "EXECUTING: " << line; ExCommand cmd; QString commandLine = QString::fromLocal8Bit(line); while (parseExCommand(&commandLine, &cmd)) { - if (!handleExCommandHelper(cmd)) - break; + if (!handleExCommandHelper(cmd)) break; } } @@ -6741,18 +6222,15 @@ bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExEchoCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExEchoCommand(const ExCommand &cmd) { // :echo - if (cmd.cmd != "echo") - return false; + if (cmd.cmd != "echo") return false; showMessage(MessageInfo, cmd.args); return true; } -void FakeVimHandler::Private::handleExCommand(const QString &line0) -{ - QString line = line0; // Make sure we have a copy to prevent aliasing. +void FakeVimHandler::Private::handleExCommand(const QString &line0) { + QString line = line0; // Make sure we have a copy to prevent aliasing. if (line.endsWith('%')) { line.chop(1); @@ -6762,7 +6240,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &line0) return; } - //qDebug() << "CMD: " << cmd; + // qDebug() << "CMD: " << cmd; enterCommandMode(g.returnToMode); @@ -6778,60 +6256,40 @@ void FakeVimHandler::Private::handleExCommand(const QString &line0) } // if the last command closed the editor, we would crash here (:vs and then :on) - if (!(m_textedit || m_plaintextedit)) - return; + if (!(m_textedit || m_plaintextedit)) return; endEditBlock(); - if (isVisualMode()) - leaveVisualMode(); + if (isVisualMode()) leaveVisualMode(); leaveCurrentMode(); } -bool FakeVimHandler::Private::handleExCommandHelper(ExCommand &cmd) -{ - return handleExPluginCommand(cmd) - || handleExGotoCommand(cmd) - || handleExBangCommand(cmd) - || handleExHistoryCommand(cmd) - || handleExRegisterCommand(cmd) - || handleExYankDeleteCommand(cmd) - || handleExChangeCommand(cmd) - || handleExMoveCommand(cmd) - || handleExJoinCommand(cmd) - || handleExMapCommand(cmd) - || handleExNohlsearchCommand(cmd) - || handleExNormalCommand(cmd) - || handleExReadCommand(cmd) - || handleExUndoRedoCommand(cmd) - || handleExSetCommand(cmd) - || handleExShiftCommand(cmd) - || handleExSortCommand(cmd) - || handleExSourceCommand(cmd) - || handleExSubstituteCommand(cmd) - || handleExTabNextCommand(cmd) - || handleExTabPreviousCommand(cmd) - || handleExWriteCommand(cmd) - || handleExEchoCommand(cmd); +bool FakeVimHandler::Private::handleExCommandHelper(ExCommand &cmd) { + return handleExPluginCommand(cmd) || handleExGotoCommand(cmd) || handleExBangCommand(cmd) || + handleExHistoryCommand(cmd) || handleExRegisterCommand(cmd) || + handleExYankDeleteCommand(cmd) || handleExChangeCommand(cmd) || + handleExMoveCommand(cmd) || handleExJoinCommand(cmd) || handleExMapCommand(cmd) || + handleExNohlsearchCommand(cmd) || handleExNormalCommand(cmd) || + handleExReadCommand(cmd) || handleExUndoRedoCommand(cmd) || handleExSetCommand(cmd) || + handleExShiftCommand(cmd) || handleExSortCommand(cmd) || handleExSourceCommand(cmd) || + handleExSubstituteCommand(cmd) || handleExTabNextCommand(cmd) || + handleExTabPreviousCommand(cmd) || handleExWriteCommand(cmd) || handleExEchoCommand(cmd); } -bool FakeVimHandler::Private::handleExPluginCommand(const ExCommand &cmd) -{ +bool FakeVimHandler::Private::handleExPluginCommand(const ExCommand &cmd) { bool handled = false; int pos = m_cursor.position(); commitCursor(); q->handleExCommandRequested(&handled, cmd); - //qDebug() << "HANDLER REQUEST: " << cmd.cmd << handled; + // qDebug() << "HANDLER REQUEST: " << cmd.cmd << handled; if (handled && (m_textedit || m_plaintextedit)) { pullCursor(); - if (m_cursor.position() != pos) - recordJump(pos); + if (m_cursor.position() != pos) recordJump(pos); } return handled; } -void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar other) -{ +void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar other) { int level = 1; int pos = position(); const int npos = forward ? lastPositionInDocument() : 0; @@ -6840,8 +6298,7 @@ void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar o ++pos; else --pos; - if (pos == npos) - return; + if (pos == npos) return; QChar c = characterAt(pos); if (c == other) ++level; @@ -6861,22 +6318,19 @@ void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar o } QTextCursor FakeVimHandler::Private::search(const SearchData &sd, int startPos, int count, - bool showMessages) -{ -#if QT_VERSION < QT_VERSION_CHECK(5,5,0) + bool showMessages) { +#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) const QRegExp needleExp = vimPatternToQtPattern(sd.needle); #else const QRegularExpression needleExp = vimPatternToQtPattern(sd.needle); #endif - if (!needleExp.isValid()) { if (showMessages) { QString error = needleExp.errorString(); showMessage(MessageError, Tr::tr("Invalid regular expression: %1").arg(error)); } - if (sd.highlightMatches) - highlightMatches(QString()); + if (sd.highlightMatches) highlightMatches(QString()); return QTextCursor(); } @@ -6887,8 +6341,7 @@ QTextCursor FakeVimHandler::Private::search(const SearchData &sd, int startPos, if (pos >= 0 && pos < document()->characterCount()) { tc = QTextCursor(document()); tc.setPosition(pos); - if (sd.forward && afterEndOfLine(document(), pos)) - tc.movePosition(Right); + if (sd.forward && afterEndOfLine(document(), pos)) tc.movePosition(Right); if (!tc.isNull()) { if (sd.forward) @@ -6908,31 +6361,26 @@ QTextCursor FakeVimHandler::Private::search(const SearchData &sd, int startPos, searchBackward(&tc, needleExp, &repeat); if (tc.isNull()) { if (showMessages) { - showMessage(MessageError, - Tr::tr("Pattern not found: %1").arg(sd.needle)); + showMessage(MessageError, Tr::tr("Pattern not found: %1").arg(sd.needle)); } } else if (showMessages) { - QString msg = sd.forward - ? Tr::tr("Search hit BOTTOM, continuing at TOP.") - : Tr::tr("Search hit TOP, continuing at BOTTOM."); + QString msg = sd.forward ? Tr::tr("Search hit BOTTOM, continuing at TOP.") + : Tr::tr("Search hit TOP, continuing at BOTTOM."); showMessage(MessageWarning, msg); } } else if (showMessages) { - QString msg = sd.forward - ? Tr::tr("Search hit BOTTOM without match for: %1") - : Tr::tr("Search hit TOP without match for: %1"); + QString msg = sd.forward ? Tr::tr("Search hit BOTTOM without match for: %1") + : Tr::tr("Search hit TOP without match for: %1"); showMessage(MessageError, msg.arg(sd.needle)); } } - if (sd.highlightMatches) - highlightMatches(needleExp.pattern()); + if (sd.highlightMatches) highlightMatches(needleExp.pattern()); return tc; } -void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages) -{ +void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages) { const int oldLine = cursorLine() - cursorLineOnScreen(); QTextCursor tc = search(sd, m_searchStartPosition, count(), showMessages); @@ -6959,8 +6407,7 @@ void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages) setTargetColumn(); } -bool FakeVimHandler::Private::searchNext(bool forward) -{ +bool FakeVimHandler::Private::searchNext(bool forward) { SearchData sd; sd.needle = g.lastSearch; sd.forward = forward ? g.lastSearchForward : !g.lastSearchForward; @@ -6972,45 +6419,38 @@ bool FakeVimHandler::Private::searchNext(bool forward) return finishSearch(); } -void FakeVimHandler::Private::highlightMatches(const QString &needle) -{ +void FakeVimHandler::Private::highlightMatches(const QString &needle) { g.lastNeedle = needle; g.highlightsCleared = false; updateHighlights(); } -void FakeVimHandler::Private::moveToFirstNonBlankOnLine() -{ +void FakeVimHandler::Private::moveToFirstNonBlankOnLine() { g.movetype = MoveLineWise; moveToFirstNonBlankOnLine(&m_cursor); setTargetColumn(); } -void FakeVimHandler::Private::moveToFirstNonBlankOnLine(QTextCursor *tc) -{ +void FakeVimHandler::Private::moveToFirstNonBlankOnLine(QTextCursor *tc) { tc->setPosition(tc->block().position(), KeepAnchor); moveToNonBlankOnLine(tc); } -void FakeVimHandler::Private::moveToFirstNonBlankOnLineVisually() -{ +void FakeVimHandler::Private::moveToFirstNonBlankOnLineVisually() { moveToStartOfLineVisually(); moveToNonBlankOnLine(&m_cursor); setTargetColumn(); } -void FakeVimHandler::Private::moveToNonBlankOnLine(QTextCursor *tc) -{ +void FakeVimHandler::Private::moveToNonBlankOnLine(QTextCursor *tc) { const QTextBlock block = tc->block(); const int maxPos = block.position() + block.length() - 1; int i = tc->position(); - while (characterAt(i).isSpace() && i < maxPos) - ++i; + while (characterAt(i).isSpace() && i < maxPos) ++i; tc->setPosition(i, KeepAnchor); } -void FakeVimHandler::Private::indentSelectedText(QChar typedChar) -{ +void FakeVimHandler::Private::indentSelectedText(QChar typedChar) { beginEditBlock(); setTargetColumn(); int beginLine = qMin(lineForPosition(position()), lineForPosition(anchor())); @@ -7026,16 +6466,13 @@ void FakeVimHandler::Private::indentSelectedText(QChar typedChar) endEditBlock(); const int lines = endLine - beginLine + 1; - if (lines > 2) - showMessage(MessageInfo, Tr::tr("%n lines indented.", nullptr, lines)); + if (lines > 2) showMessage(MessageInfo, Tr::tr("%n lines indented.", nullptr, lines)); } -void FakeVimHandler::Private::indentText(const Range &range, QChar typedChar) -{ +void FakeVimHandler::Private::indentText(const Range &range, QChar typedChar) { int beginBlock = blockAt(range.beginPos).blockNumber(); int endBlock = blockAt(range.endPos).blockNumber(); - if (beginBlock > endBlock) - std::swap(beginBlock, endBlock); + if (beginBlock > endBlock) std::swap(beginBlock, endBlock); // Don't remember current indentation in last text insertion. const QString lastInsertion = m_buffer->lastInsertion; @@ -7043,15 +6480,13 @@ void FakeVimHandler::Private::indentText(const Range &range, QChar typedChar) m_buffer->lastInsertion = lastInsertion; } -bool FakeVimHandler::Private::isElectricCharacter(QChar c) const -{ +bool FakeVimHandler::Private::isElectricCharacter(QChar c) const { bool result = false; q->checkForElectricCharacter(&result, c); return result; } -void FakeVimHandler::Private::shiftRegionRight(int repeat) -{ +void FakeVimHandler::Private::shiftRegionRight(int repeat) { int beginLine = lineForPosition(anchor()); int endLine = lineForPosition(position()); int targetPos = anchor(); @@ -7059,8 +6494,7 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat) std::swap(beginLine, endLine); targetPos = position(); } - if (s.startOfLine.value()) - targetPos = firstPositionInLine(beginLine); + if (s.startOfLine.value()) targetPos = firstPositionInLine(beginLine); const int sw = s.shiftWidth.value(); g.movetype = MoveLineWise; @@ -7070,8 +6504,7 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat) const Column col = indentation(block.text()); QTextCursor tc = m_cursor; tc.setPosition(block.position()); - if (col.physical > 0) - tc.setPosition(tc.position() + col.physical, KeepAnchor); + if (col.physical > 0) tc.setPosition(tc.position() + col.physical, KeepAnchor); tc.insertText(tabExpand(col.logical + sw * repeat)); block = block.next(); } @@ -7082,34 +6515,29 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat) const int lines = endLine - beginLine + 1; if (lines > 2) { - showMessage(MessageInfo, - Tr::tr("%n lines %1ed %2 time.", nullptr, lines) - .arg(repeat > 0 ? '>' : '<').arg(qAbs(repeat))); + showMessage(MessageInfo, Tr::tr("%n lines %1ed %2 time.", nullptr, lines) + .arg(repeat > 0 ? '>' : '<') + .arg(qAbs(repeat))); } } -void FakeVimHandler::Private::shiftRegionLeft(int repeat) -{ - shiftRegionRight(-repeat); -} +void FakeVimHandler::Private::shiftRegionLeft(int repeat) { shiftRegionRight(-repeat); } -void FakeVimHandler::Private::moveToTargetColumn() -{ +void FakeVimHandler::Private::moveToTargetColumn() { const QTextBlock &bl = block(); - //Column column = cursorColumn(); - //int logical = logical + // Column column = cursorColumn(); + // int logical = logical const int pos = lastPositionInLine(bl.blockNumber() + 1, false); if (m_targetColumn == -1) { setPosition(pos); return; } const int physical = bl.position() + logicalToPhysicalColumn(m_targetColumn, bl.text()); - //qDebug() << "CORRECTING COLUMN FROM: " << logical << "TO" << m_targetColumn; + // qDebug() << "CORRECTING COLUMN FROM: " << logical << "TO" << m_targetColumn; setPosition(qMin(pos, physical)); } -void FakeVimHandler::Private::setTargetColumn() -{ +void FakeVimHandler::Private::setTargetColumn() { m_targetColumn = logicalCursorColumn(); m_visualTargetColumn = m_targetColumn; @@ -7127,27 +6555,22 @@ void FakeVimHandler::Private::setTargetColumn() * class 2: letter-or-number */ - -int FakeVimHandler::Private::charClass(QChar c, bool simple) const -{ - if (simple) - return c.isSpace() ? 0 : 1; +int FakeVimHandler::Private::charClass(QChar c, bool simple) const { + if (simple) return c.isSpace() ? 0 : 1; // FIXME: This means that only characters < 256 in the // ConfigIsKeyword setting are handled properly. if (c.unicode() < 256) { - //int old = (c.isLetterOrNumber() || c.unicode() == '_') ? 2 - // : c.isSpace() ? 0 : 1; - //qDebug() << c.unicode() << old << m_charClass[c.unicode()]; + // int old = (c.isLetterOrNumber() || c.unicode() == '_') ? 2 + // : c.isSpace() ? 0 : 1; + // qDebug() << c.unicode() << old << m_charClass[c.unicode()]; return m_charClass[c.unicode()]; } - if (c.isLetterOrNumber() || c == '_') - return 2; + if (c.isLetterOrNumber() || c == '_') return 2; return c.isSpace() ? 0 : 1; } void FakeVimHandler::Private::miniBufferTextEdited(const QString &text, int cursorPos, - int anchorPos) -{ + int anchorPos) { if (!isCommandLineMode()) { editor()->setFocus(); } else if (text.isEmpty()) { @@ -7179,8 +6602,7 @@ void FakeVimHandler::Private::miniBufferTextEdited(const QString &text, int curs } } -void FakeVimHandler::Private::pullOrCreateBufferData() -{ +void FakeVimHandler::Private::pullOrCreateBufferData() { const QVariant data = document()->property("FakeVimSharedData"); if (data.isValid()) { // FakeVimHandler has been already created for this document (e.g. in other split). @@ -7191,22 +6613,17 @@ void FakeVimHandler::Private::pullOrCreateBufferData() document()->setProperty("FakeVimSharedData", QVariant::fromValue(m_buffer)); } - if (editor()->hasFocus()) - m_buffer->currentHandler = this; + if (editor()->hasFocus()) m_buffer->currentHandler = this; } // Helper to parse a-z,A-Z,48-57,_ -static int someInt(const QString &str) -{ - if (str.toInt()) - return str.toInt(); - if (!str.isEmpty()) - return str.at(0).unicode(); +static int someInt(const QString &str) { + if (str.toInt()) return str.toInt(); + if (!str.isEmpty()) return str.at(0).unicode(); return 0; } -void FakeVimHandler::Private::setupCharClass() -{ +void FakeVimHandler::Private::setupCharClass() { for (int i = 0; i < 256; ++i) { const QChar c = QLatin1Char(i); m_charClass[i] = c.isSpace() ? 0 : 1; @@ -7216,20 +6633,17 @@ void FakeVimHandler::Private::setupCharClass() if (part.contains('-')) { const int from = someInt(part.section('-', 0, 0)); const int to = someInt(part.section('-', 1, 1)); - for (int i = qMax(0, from); i <= qMin(255, to); ++i) - m_charClass[i] = 2; + for (int i = qMax(0, from); i <= qMin(255, to); ++i) m_charClass[i] = 2; } else { m_charClass[qMin(255, someInt(part))] = 2; } } } -void FakeVimHandler::Private::moveToBoundary(bool simple, bool forward) -{ +void FakeVimHandler::Private::moveToBoundary(bool simple, bool forward) { QTextCursor tc(document()); tc.setPosition(position()); - if (forward ? tc.atBlockEnd() : tc.atBlockStart()) - return; + if (forward ? tc.atBlockEnd() : tc.atBlockStart()) return; QChar c = characterAt(tc.position() + (forward ? -1 : 1)); int lastClass = tc.atStart() ? -1 : charClass(c, simple); @@ -7238,8 +6652,7 @@ void FakeVimHandler::Private::moveToBoundary(bool simple, bool forward) c = characterAt(tc.position()); int thisClass = charClass(c, simple); if (thisClass != lastClass || (forward ? tc.atBlockEnd() : tc.atBlockStart())) { - if (tc != m_cursor) - tc.movePosition(forward ? Left : Right); + if (tc != m_cursor) tc.movePosition(forward ? Left : Right); break; } lastClass = thisClass; @@ -7248,88 +6661,78 @@ void FakeVimHandler::Private::moveToBoundary(bool simple, bool forward) setPosition(tc.position()); } -void FakeVimHandler::Private::moveToNextBoundary(bool end, int count, bool simple, bool forward) -{ +void FakeVimHandler::Private::moveToNextBoundary(bool end, int count, bool simple, bool forward) { int repeat = count; while (repeat > 0 && !(forward ? atDocumentEnd() : atDocumentStart())) { setPosition(position() + (forward ? 1 : -1)); moveToBoundary(simple, forward); - if (atBoundary(end, simple)) - --repeat; + if (atBoundary(end, simple)) --repeat; } } -void FakeVimHandler::Private::moveToNextBoundaryStart(int count, bool simple, bool forward) -{ +void FakeVimHandler::Private::moveToNextBoundaryStart(int count, bool simple, bool forward) { moveToNextBoundary(false, count, simple, forward); } -void FakeVimHandler::Private::moveToNextBoundaryEnd(int count, bool simple, bool forward) -{ +void FakeVimHandler::Private::moveToNextBoundaryEnd(int count, bool simple, bool forward) { moveToNextBoundary(true, count, simple, forward); } -void FakeVimHandler::Private::moveToBoundaryStart(int count, bool simple, bool forward) -{ +void FakeVimHandler::Private::moveToBoundaryStart(int count, bool simple, bool forward) { moveToNextBoundaryStart(atBoundary(false, simple) ? count - 1 : count, simple, forward); } -void FakeVimHandler::Private::moveToBoundaryEnd(int count, bool simple, bool forward) -{ +void FakeVimHandler::Private::moveToBoundaryEnd(int count, bool simple, bool forward) { moveToNextBoundaryEnd(atBoundary(true, simple) ? count - 1 : count, simple, forward); } -void FakeVimHandler::Private::moveToNextWord(bool end, int count, bool simple, bool forward, bool emptyLines) -{ +void FakeVimHandler::Private::moveToNextWord(bool end, int count, bool simple, bool forward, + bool emptyLines) { int repeat = count; while (repeat > 0 && !(forward ? atDocumentEnd() : atDocumentStart())) { setPosition(position() + (forward ? 1 : -1)); moveToBoundary(simple, forward); - if (atWordBoundary(end, simple) && (emptyLines || !atEmptyLine()) ) - --repeat; + if (atWordBoundary(end, simple) && (emptyLines || !atEmptyLine())) --repeat; } } -void FakeVimHandler::Private::moveToNextWordStart(int count, bool simple, bool forward, bool emptyLines) -{ +void FakeVimHandler::Private::moveToNextWordStart(int count, bool simple, bool forward, + bool emptyLines) { g.movetype = MoveExclusive; moveToNextWord(false, count, simple, forward, emptyLines); setTargetColumn(); } -void FakeVimHandler::Private::moveToNextWordEnd(int count, bool simple, bool forward, bool emptyLines) -{ +void FakeVimHandler::Private::moveToNextWordEnd(int count, bool simple, bool forward, + bool emptyLines) { g.movetype = MoveInclusive; moveToNextWord(true, count, simple, forward, emptyLines); setTargetColumn(); } -void FakeVimHandler::Private::moveToWordStart(int count, bool simple, bool forward, bool emptyLines) -{ +void FakeVimHandler::Private::moveToWordStart(int count, bool simple, bool forward, + bool emptyLines) { moveToNextWordStart(atWordStart(simple) ? count - 1 : count, simple, forward, emptyLines); } -void FakeVimHandler::Private::moveToWordEnd(int count, bool simple, bool forward, bool emptyLines) -{ +void FakeVimHandler::Private::moveToWordEnd(int count, bool simple, bool forward, bool emptyLines) { moveToNextWordEnd(atWordEnd(simple) ? count - 1 : count, simple, forward, emptyLines); } -bool FakeVimHandler::Private::handleFfTt(const QString &key, bool repeats) -{ +bool FakeVimHandler::Private::handleFfTt(const QString &key, bool repeats) { int key0 = key.size() == 1 ? key.at(0).unicode() : 0; // g.subsubmode \in { 'f', 'F', 't', 'T' } bool forward = g.subsubdata.is('f') || g.subsubdata.is('t'); - bool exclusive = g.subsubdata.is('t') || g.subsubdata.is('T'); + bool exclusive = g.subsubdata.is('t') || g.subsubdata.is('T'); int repeat = count(); - int n = block().position() + (forward ? block().length() : - 1); + int n = block().position() + (forward ? block().length() : -1); const int d = forward ? 1 : -1; // FIXME: This also depends on whether 'cpositions' Vim option contains ';'. const int skip = (repeats && repeat == 1 && exclusive) ? d : 0; int pos = position() + d + skip; for (; repeat > 0 && (forward ? pos < n : pos > n); pos += d) { - if (characterAt(pos).unicode() == key0) - --repeat; + if (characterAt(pos).unicode() == key0) --repeat; } if (repeat == 0) { @@ -7341,8 +6744,7 @@ bool FakeVimHandler::Private::handleFfTt(const QString &key, bool repeats) return false; } -void FakeVimHandler::Private::moveToMatchingParanthesis() -{ +void FakeVimHandler::Private::moveToMatchingParanthesis() { bool moved = false; bool forward = false; @@ -7354,73 +6756,59 @@ void FakeVimHandler::Private::moveToMatchingParanthesis() while (!parenthesesChars.contains(characterAt(tc.position())) && !tc.atBlockEnd()) tc.setPosition(tc.position() + 1); - if (tc.atBlockEnd()) - tc = m_cursor; + if (tc.atBlockEnd()) tc = m_cursor; q->moveToMatchingParenthesis(&moved, &forward, &tc); if (moved) { - if (forward) - tc.movePosition(Left, KeepAnchor, 1); + if (forward) tc.movePosition(Left, KeepAnchor, 1); setAnchorAndPosition(anc, tc.position()); setTargetColumn(); } } -int FakeVimHandler::Private::cursorLineOnScreen() const -{ - if (!editor()) - return 0; +int FakeVimHandler::Private::cursorLineOnScreen() const { + if (!editor()) return 0; const QRect rect = EDITOR(cursorRect(m_cursor)); return rect.height() > 0 ? rect.y() / rect.height() : 0; } -int FakeVimHandler::Private::linesOnScreen() const -{ - if (!editor()) - return 1; +int FakeVimHandler::Private::linesOnScreen() const { + if (!editor()) return 1; const int h = EDITOR(cursorRect(m_cursor)).height(); return h > 0 ? EDITOR(viewport()->height()) / h : 1; } -int FakeVimHandler::Private::cursorLine() const -{ - return lineForPosition(position()) - 1; -} +int FakeVimHandler::Private::cursorLine() const { return lineForPosition(position()) - 1; } -int FakeVimHandler::Private::cursorBlockNumber() const -{ +int FakeVimHandler::Private::cursorBlockNumber() const { return blockAt(qMin(anchor(), position())).blockNumber(); } -int FakeVimHandler::Private::physicalCursorColumn() const -{ +int FakeVimHandler::Private::physicalCursorColumn() const { return position() - block().position(); } -int FakeVimHandler::Private::physicalToLogicalColumn - (const int physical, const QString &line) const -{ +int FakeVimHandler::Private::physicalToLogicalColumn(const int physical, + const QString &line) const { const int ts = s.tabStop.value(); int p = 0; int logical = 0; while (p < physical) { QChar c = line.at(p); - //if (c == ' ') - // ++logical; - //else + // if (c == ' ') + // ++logical; + // else if (c == '\t') logical += ts - logical % ts; else ++logical; - //break; + // break; ++p; } return logical; } -int FakeVimHandler::Private::logicalToPhysicalColumn - (const int logical, const QString &line) const -{ +int FakeVimHandler::Private::logicalToPhysicalColumn(const int logical, const QString &line) const { const int ts = s.tabStop.value(); int physical = 0; for (int l = 0; l < logical && physical < line.size(); ++physical) { @@ -7433,36 +6821,29 @@ int FakeVimHandler::Private::logicalToPhysicalColumn return physical; } -int FakeVimHandler::Private::windowScrollOffset() const -{ +int FakeVimHandler::Private::windowScrollOffset() const { return qMin(static_cast(s.scrollOff.value()), linesOnScreen() / 2); } -int FakeVimHandler::Private::logicalCursorColumn() const -{ +int FakeVimHandler::Private::logicalCursorColumn() const { const int physical = physicalCursorColumn(); const QString line = block().text(); return physicalToLogicalColumn(physical, line); } -Column FakeVimHandler::Private::cursorColumn() const -{ +Column FakeVimHandler::Private::cursorColumn() const { return Column(physicalCursorColumn(), logicalCursorColumn()); } -int FakeVimHandler::Private::linesInDocument() const -{ - if (m_cursor.isNull()) - return 0; +int FakeVimHandler::Private::linesInDocument() const { + if (m_cursor.isNull()) return 0; return document()->blockCount(); } -void FakeVimHandler::Private::scrollToLine(int line) -{ +void FakeVimHandler::Private::scrollToLine(int line) { // Don't scroll if the line is already at the top. updateFirstVisibleLine(); - if (line == m_firstVisibleLine) - return; + if (line == m_firstVisibleLine) return; const QTextCursor tc = m_cursor; @@ -7480,7 +6861,7 @@ void FakeVimHandler::Private::scrollToLine(int line) QTextLine textLine = block.layout()->lineAt(lineInBlock); offset = textLine.textStart(); } else { -// QTC_CHECK(false); + // QTC_CHECK(false); } } tc2.setPosition(block.position() + offset); @@ -7492,46 +6873,37 @@ void FakeVimHandler::Private::scrollToLine(int line) m_firstVisibleLine = line; } -void FakeVimHandler::Private::updateFirstVisibleLine() -{ - const QTextCursor tc = EDITOR(cursorForPosition(QPoint(0,0))); +void FakeVimHandler::Private::updateFirstVisibleLine() { + const QTextCursor tc = EDITOR(cursorForPosition(QPoint(0, 0))); m_firstVisibleLine = lineForPosition(tc.position()) - 1; } -int FakeVimHandler::Private::firstVisibleLine() const -{ - return m_firstVisibleLine; -} +int FakeVimHandler::Private::firstVisibleLine() const { return m_firstVisibleLine; } -int FakeVimHandler::Private::lastVisibleLine() const -{ +int FakeVimHandler::Private::lastVisibleLine() const { const int line = m_firstVisibleLine + linesOnScreen(); const QTextBlock block = document()->findBlockByLineNumber(line); return block.isValid() ? line : document()->lastBlock().firstLineNumber(); } -int FakeVimHandler::Private::lineOnTop(int count) const -{ +int FakeVimHandler::Private::lineOnTop(int count) const { const int scrollOffset = qMax(count - 1, windowScrollOffset()); const int line = firstVisibleLine(); return line == 0 ? count - 1 : scrollOffset + line; } -int FakeVimHandler::Private::lineOnBottom(int count) const -{ +int FakeVimHandler::Private::lineOnBottom(int count) const { const int scrollOffset = qMax(count - 1, windowScrollOffset()); const int line = lastVisibleLine(); return line >= document()->lastBlock().firstLineNumber() ? line - count + 1 : line - scrollOffset - 1; } -void FakeVimHandler::Private::scrollUp(int count) -{ +void FakeVimHandler::Private::scrollUp(int count) { scrollToLine(cursorLine() - cursorLineOnScreen() - count); } -void FakeVimHandler::Private::updateScrollOffset() -{ +void FakeVimHandler::Private::updateScrollOffset() { const int line = cursorLine(); if (line < lineOnTop()) scrollToLine(qMax(0, line - windowScrollOffset())); @@ -7540,63 +6912,53 @@ void FakeVimHandler::Private::updateScrollOffset() } void FakeVimHandler::Private::alignViewportToCursor(AlignmentFlag align, int line, - bool moveToNonBlank) -{ - if (line > 0) - setPosition(firstPositionInLine(line)); - if (moveToNonBlank) - moveToFirstNonBlankOnLine(); + bool moveToNonBlank) { + if (line > 0) setPosition(firstPositionInLine(line)); + if (moveToNonBlank) moveToFirstNonBlankOnLine(); if (align == Qt::AlignTop) - scrollUp(- cursorLineOnScreen()); + scrollUp(-cursorLineOnScreen()); else if (align == Qt::AlignVCenter) scrollUp(linesOnScreen() / 2 - cursorLineOnScreen()); else if (align == Qt::AlignBottom) scrollUp(linesOnScreen() - cursorLineOnScreen() - 1); } -int FakeVimHandler::Private::lineToBlockNumber(int line) const -{ +int FakeVimHandler::Private::lineToBlockNumber(int line) const { return document()->findBlockByLineNumber(line).blockNumber(); } -void FakeVimHandler::Private::setCursorPosition(const CursorPosition &p) -{ +void FakeVimHandler::Private::setCursorPosition(const CursorPosition &p) { const int firstLine = firstVisibleLine(); const int firstBlock = lineToBlockNumber(firstLine); const int lastBlock = lineToBlockNumber(firstLine + linesOnScreen() - 2); bool isLineVisible = firstBlock <= p.line && p.line <= lastBlock; setCursorPosition(&m_cursor, p); - if (!isLineVisible) - alignViewportToCursor(Qt::AlignVCenter); + if (!isLineVisible) alignViewportToCursor(Qt::AlignVCenter); } -void FakeVimHandler::Private::setCursorPosition(QTextCursor *tc, const CursorPosition &p) -{ +void FakeVimHandler::Private::setCursorPosition(QTextCursor *tc, const CursorPosition &p) { const int line = qMin(document()->blockCount() - 1, p.line); QTextBlock block = document()->findBlockByNumber(line); const int column = qMin(p.column, block.length() - 1); tc->setPosition(block.position() + column, KeepAnchor); } -int FakeVimHandler::Private::lastPositionInDocument(bool ignoreMode) const -{ - return document()->characterCount() - - (ignoreMode || isVisualMode() || isInsertMode() ? 1 : 2); +int FakeVimHandler::Private::lastPositionInDocument(bool ignoreMode) const { + return document()->characterCount() - (ignoreMode || isVisualMode() || isInsertMode() ? 1 : 2); } -QString FakeVimHandler::Private::selectText(const Range &range) const -{ +QString FakeVimHandler::Private::selectText(const Range &range) const { QString contents; const QString lineEnd = range.rangemode == RangeBlockMode ? QString('\n') : QString(); QTextCursor tc = m_cursor; - transformText(range, tc, - [&tc, &contents, &lineEnd]() { contents.append(tc.selection().toPlainText() + lineEnd); }); + transformText(range, tc, [&tc, &contents, &lineEnd]() { + contents.append(tc.selection().toPlainText() + lineEnd); + }); return contents; } -void FakeVimHandler::Private::yankText(const Range &range, int reg) -{ +void FakeVimHandler::Private::yankText(const Range &range, int reg) { const QString text = selectText(range); setRegister(reg, text, range.rangemode); @@ -7618,15 +6980,13 @@ void FakeVimHandler::Private::yankText(const Range &range, int reg) setRegister('"', text, range.rangemode); } - const int lines = blockAt(range.endPos).blockNumber() - - blockAt(range.beginPos).blockNumber() + 1; - if (lines > 2) - showMessage(MessageInfo, Tr::tr("%n lines yanked.", nullptr, lines)); + const int lines = + blockAt(range.endPos).blockNumber() - blockAt(range.beginPos).blockNumber() + 1; + if (lines > 2) showMessage(MessageInfo, Tr::tr("%n lines yanked.", nullptr, lines)); } -void FakeVimHandler::Private::transformText( - const Range &range, QTextCursor &tc, const std::function &transform) const -{ +void FakeVimHandler::Private::transformText(const Range &range, QTextCursor &tc, + const std::function &transform) const { switch (range.rangemode) { case RangeCharMode: { // This can span multiple lines. @@ -7668,10 +7028,8 @@ void FakeVimHandler::Private::transformText( case RangeBlockMode: { int beginColumn = columnAt(range.beginPos); int endColumn = columnAt(range.endPos); - if (endColumn < beginColumn) - std::swap(beginColumn, endColumn); - if (range.rangemode == RangeBlockAndTailMode) - endColumn = INT_MAX - 1; + if (endColumn < beginColumn) std::swap(beginColumn, endColumn); + if (range.rangemode == RangeBlockAndTailMode) endColumn = INT_MAX - 1; QTextBlock block = document()->findBlock(range.beginPos); const QTextBlock lastBlock = document()->findBlock(range.endPos); while (block.isValid() && block.position() <= lastBlock.position()) { @@ -7688,104 +7046,91 @@ void FakeVimHandler::Private::transformText( } } -void FakeVimHandler::Private::transformText(const Range &range, const Transformation &transform) -{ +void FakeVimHandler::Private::transformText(const Range &range, const Transformation &transform) { beginEditBlock(); - transformText(range, m_cursor, - [this, &transform] { m_cursor.insertText(transform(m_cursor.selection().toPlainText())); }); + transformText(range, m_cursor, [this, &transform] { + m_cursor.insertText(transform(m_cursor.selection().toPlainText())); + }); endEditBlock(); setTargetColumn(); } -void FakeVimHandler::Private::insertText(QTextCursor &tc, const QString &text) -{ - if (s.passKeys.value()) { - if (tc.hasSelection() && text.isEmpty()) { - QKeyEvent event(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, QString()); - passEventToEditor(event, tc); - } +void FakeVimHandler::Private::insertText(QTextCursor &tc, const QString &text) { + if (s.passKeys.value()) { + if (tc.hasSelection() && text.isEmpty()) { + QKeyEvent event(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, QString()); + passEventToEditor(event, tc); + } - for (QChar c : text) { - QKeyEvent event(QEvent::KeyPress, -1, Qt::NoModifier, QString(c)); - passEventToEditor(event, tc); - } - } else { - tc.insertText(text); - } + for (QChar c : text) { + QKeyEvent event(QEvent::KeyPress, -1, Qt::NoModifier, QString(c)); + passEventToEditor(event, tc); + } + } else { + tc.insertText(text); + } } -void FakeVimHandler::Private::insertText(const Register ®) -{ +void FakeVimHandler::Private::insertText(const Register ®) { if (reg.rangemode != RangeCharMode) { qWarning() << "WRONG INSERT MODE: " << reg.rangemode; return; } setAnchor(); m_cursor.insertText(reg.contents); - //dump("AFTER INSERT"); + // dump("AFTER INSERT"); } -void FakeVimHandler::Private::removeText(const Range &range) -{ +void FakeVimHandler::Private::removeText(const Range &range) { transformText(range, [](const QString &) { return QString(); }); } -void FakeVimHandler::Private::downCase(const Range &range) -{ - transformText(range, [](const QString &text) { return text.toLower(); } ); +void FakeVimHandler::Private::downCase(const Range &range) { + transformText(range, [](const QString &text) { return text.toLower(); }); } -void FakeVimHandler::Private::upCase(const Range &range) -{ - transformText(range, [](const QString &text) { return text.toUpper(); } ); +void FakeVimHandler::Private::upCase(const Range &range) { + transformText(range, [](const QString &text) { return text.toUpper(); }); } -void FakeVimHandler::Private::invertCase(const Range &range) -{ - transformText(range, - [] (const QString &text) -> QString { - QString result = text; - for (int i = 0; i < result.length(); ++i) { - const QChar c = result[i]; - result[i] = c.isUpper() ? c.toLower() : c.toUpper(); - } - return result; +void FakeVimHandler::Private::invertCase(const Range &range) { + transformText(range, [](const QString &text) -> QString { + QString result = text; + for (int i = 0; i < result.length(); ++i) { + const QChar c = result[i]; + result[i] = c.isUpper() ? c.toLower() : c.toUpper(); + } + return result; }); } -void FakeVimHandler::Private::toggleComment(const Range &range) -{ - static const QMap extensionToCommentString { - {"pri", "#"}, - {"pro", "#"}, - {"h", "//"}, - {"hpp", "//"}, - {"cpp", "//"}, +void FakeVimHandler::Private::toggleComment(const Range &range) { + static const QMap extensionToCommentString{ + {"pri", "#"}, {"pro", "#"}, {"h", "//"}, {"hpp", "//"}, {"cpp", "//"}, }; - const QString commentString = extensionToCommentString.value(QFileInfo(m_currentFileName).suffix(), "//"); - - transformText(range, - [&commentString] (const QString &text) -> QString { + const QString commentString = + extensionToCommentString.value(QFileInfo(m_currentFileName).suffix(), "//"); + transformText(range, [&commentString](const QString &text) -> QString { QStringList lines = text.split('\n'); - const QRegularExpression checkForComment("^\\s*" - + QRegularExpression::escape(commentString)); + const QRegularExpression checkForComment("^\\s*" + + QRegularExpression::escape(commentString)); - const bool firstLineIsComment - = !lines.empty() && lines.front().contains(checkForComment); + const bool firstLineIsComment = !lines.empty() && lines.front().contains(checkForComment); - for (auto& line : lines) { + for (auto &line : lines) { if (!line.isEmpty()) { if (firstLineIsComment) { - const bool hasSpaceAfterCommentString = line.contains( - QRegularExpression(checkForComment.pattern() + "\\s")); + const bool hasSpaceAfterCommentString = + line.contains(QRegularExpression(checkForComment.pattern() + "\\s")); const int sizeToReplace = hasSpaceAfterCommentString ? commentString.size() + 1 - : commentString.size(); + : commentString.size(); line.replace(line.indexOf(commentString), sizeToReplace, ""); } else { const int indexOfFirstNonSpace = line.indexOf(QRegularExpression("[^\\s]")); - line = line.left(indexOfFirstNonSpace) + commentString + " " + line.right(line.size() - indexOfFirstNonSpace); + line = line.left(indexOfFirstNonSpace) + commentString + " " + + line.right(line.size() - indexOfFirstNonSpace); } } } @@ -7794,16 +7139,14 @@ void FakeVimHandler::Private::toggleComment(const Range &range) }); } -void FakeVimHandler::Private::exchangeRange(const Range &range) -{ +void FakeVimHandler::Private::exchangeRange(const Range &range) { if (g.exchangeRange) { pushUndoState(false); beginEditBlock(); Range leftRange = *g.exchangeRange; Range rightRange = range; - if (leftRange.beginPos > rightRange.beginPos) - std::swap(leftRange, rightRange); + if (leftRange.beginPos > rightRange.beginPos) std::swap(leftRange, rightRange); // First replace the right range, then left one // If we did it the other way around, we would invalidate the positions @@ -7820,29 +7163,24 @@ void FakeVimHandler::Private::exchangeRange(const Range &range) } } -void FakeVimHandler::Private::replaceWithRegister(const Range &range) -{ +void FakeVimHandler::Private::replaceWithRegister(const Range &range) { replaceText(range, registerContents(m_register)); } -void FakeVimHandler::Private::surroundCurrentRange(const Input &input, const QString &prefix) -{ +void FakeVimHandler::Private::surroundCurrentRange(const Input &input, const QString &prefix) { QString dotCommand; - if (isVisualMode()) - dotCommand = visualDotCommand() + "S" + input.asChar(); + if (isVisualMode()) dotCommand = visualDotCommand() + "S" + input.asChar(); const bool wasVisualCharMode = isVisualCharMode(); const bool wasVisualLineMode = isVisualLineMode(); leaveVisualMode(); - if (dotCommand.isEmpty()) { // i.e. we came from normal mode - dotCommand = dotCommandFromSubMode(g.submode) - + QLatin1Char(g.surroundUpperCaseS ? 'S' : 's') - + g.dotCommand + input.asChar(); + if (dotCommand.isEmpty()) { // i.e. we came from normal mode + dotCommand = dotCommandFromSubMode(g.submode) + + QLatin1Char(g.surroundUpperCaseS ? 'S' : 's') + g.dotCommand + input.asChar(); } - if (wasVisualCharMode) - setPosition(position() + 1); + if (wasVisualCharMode) setPosition(position() + 1); QString newFront, newBack; @@ -7876,34 +7214,29 @@ void FakeVimHandler::Private::surroundCurrentRange(const Input &input, const QSt newBack = " " + newBack; } - if (!newFront.isEmpty()) { transformText(currentRange(), [&](QString text) -> QString { - if (newFront == QChar()) - return text.mid(1, text.size() - 2); + if (newFront == QChar()) return text.mid(1, text.size() - 2); - const QString newMiddle = (g.submode == ChangeSurroundingSubMode) ? - text.mid(1, text.size() - 2) : text; + const QString newMiddle = + (g.submode == ChangeSurroundingSubMode) ? text.mid(1, text.size() - 2) : text; return prefix + newFront + newMiddle + newBack; }); } // yS, cS and VS also indent the surrounded text - if (g.surroundUpperCaseS || wasVisualLineMode) - replay(QStringLiteral("=a") + input.asChar()); + if (g.surroundUpperCaseS || wasVisualLineMode) replay(QStringLiteral("=a") + input.asChar()); // Indenting has changed the dotCommand, so now set it back to the correct one g.dotCommand = dotCommand; } -void FakeVimHandler::Private::replaceText(const Range &range, const QString &str) -{ - transformText(range, [&str](const QString &) { return str; } ); +void FakeVimHandler::Private::replaceText(const Range &range, const QString &str) { + transformText(range, [&str](const QString &) { return str; }); } -void FakeVimHandler::Private::pasteText(bool afterCursor) -{ +void FakeVimHandler::Private::pasteText(bool afterCursor) { const QString text = registerContents(m_register); const RangeMode rangeMode = registerRangeMode(m_register); @@ -7912,15 +7245,13 @@ void FakeVimHandler::Private::pasteText(bool afterCursor) // In visual mode paste text only inside selection. bool pasteAfter = isVisualMode() ? false : afterCursor; - if (isVisualMode()) - cutSelectedText(g.submode == ReplaceWithRegisterSubMode ? '-' : '"'); + if (isVisualMode()) cutSelectedText(g.submode == ReplaceWithRegisterSubMode ? '-' : '"'); switch (rangeMode) { case RangeCharMode: { m_targetColumn = 0; const int pos = position() + 1; - if (pasteAfter && rightDist() > 0) - moveRight(); + if (pasteAfter && rightDist() > 0) moveRight(); insertText(text.repeated(count())); if (text.contains('\n')) setPosition(pos); @@ -7954,8 +7285,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor) case RangeBlockAndTailMode: case RangeBlockMode: { const int pos = position(); - if (pasteAfter && rightDist() > 0) - moveRight(); + if (pasteAfter && rightDist() > 0) moveRight(); QTextCursor tc = m_cursor; const int col = tc.columnNumber(); QTextBlock block = tc.block(); @@ -7985,8 +7315,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor) block = block.next(); } setPosition(pos); - if (pasteAfter) - moveRight(); + if (pasteAfter) moveRight(); break; } } @@ -7994,19 +7323,16 @@ void FakeVimHandler::Private::pasteText(bool afterCursor) endEditBlock(); } -void FakeVimHandler::Private::cutSelectedText(int reg) -{ +void FakeVimHandler::Private::cutSelectedText(int reg) { pushUndoState(); bool visualMode = isVisualMode(); leaveVisualMode(); Range range = currentRange(); - if (visualMode && g.rangemode == RangeCharMode) - ++range.endPos; + if (visualMode && g.rangemode == RangeCharMode) ++range.endPos; - if (!reg) - reg = m_register; + if (!reg) reg = m_register; g.submode = DeleteSubMode; yankText(range, reg); @@ -8019,16 +7345,15 @@ void FakeVimHandler::Private::cutSelectedText(int reg) setPosition(qMin(position(), anchor())); } -void FakeVimHandler::Private::joinLines(int count, bool preserveSpace) -{ +void FakeVimHandler::Private::joinLines(int count, bool preserveSpace) { int pos = position(); const int blockNumber = m_cursor.blockNumber(); const QString currentLine = lineContents(blockNumber + 1); - const bool startingLineIsComment - = currentLine.contains(QRegularExpression("^\\s*\\/\\/")) // Cpp-style - || currentLine.contains(QRegularExpression("^\\s*\\/?\\*")) // C-style - || currentLine.contains(QRegularExpression("^\\s*#")); // Python/Shell-style + const bool startingLineIsComment = + currentLine.contains(QRegularExpression("^\\s*\\/\\/")) // Cpp-style + || currentLine.contains(QRegularExpression("^\\s*\\/?\\*")) // C-style + || currentLine.contains(QRegularExpression("^\\s*#")); // Python/Shell-style for (int i = qMax(count - 2, 0); i >= 0 && blockNumber < document()->blockCount(); --i) { moveBehindEndOfLine(); @@ -8038,18 +7363,17 @@ void FakeVimHandler::Private::joinLines(int count, bool preserveSpace) if (preserveSpace) { removeText(currentRange()); } else { - while (characterAtCursor() == ' ' || characterAtCursor() == '\t') - moveRight(); + while (characterAtCursor() == ' ' || characterAtCursor() == '\t') moveRight(); - // If the line we started from is a comment, remove the comment string from the next line + // If the line we started from is a comment, remove the comment string from the next + // line if (startingLineIsComment && s.formatOptions.value().contains('f')) { if (characterAtCursor() == '/' && characterAt(position() + 1) == '/') moveRight(2); else if (characterAtCursor() == '*' || characterAtCursor() == '#') moveRight(1); - if (characterAtCursor() == ' ') - moveRight(); + if (characterAtCursor() == ' ') moveRight(); } m_cursor.insertText(QString(' ')); @@ -8058,29 +7382,26 @@ void FakeVimHandler::Private::joinLines(int count, bool preserveSpace) setPosition(pos); } -void FakeVimHandler::Private::insertNewLine() -{ +void FakeVimHandler::Private::insertNewLine() { if (m_buffer->editBlockLevel <= 1 && s.passKeys.value()) { QKeyEvent event(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "\n"); - if (passEventToEditor(event, m_cursor)) - return; + if (passEventToEditor(event, m_cursor)) return; } insertText(QStringLiteral("\n")); insertAutomaticIndentation(true); } -bool FakeVimHandler::Private::handleInsertInEditor(const Input &input) -{ - if (m_buffer->editBlockLevel > 0 || !s.passKeys.value()) - return false; +bool FakeVimHandler::Private::handleInsertInEditor(const Input &input) { + if (m_buffer->editBlockLevel > 0 || !s.passKeys.value()) return false; joinPreviousEditBlock(); QKeyEvent event(QEvent::KeyPress, input.key(), input.modifiers(), input.text()); setAnchor(); if (!passEventToEditor(event, m_cursor)) - return !m_textedit && !m_plaintextedit; // Mark event as handled if it has destroyed editor. + return !m_textedit && + !m_plaintextedit; // Mark event as handled if it has destroyed editor. endEditBlock(); @@ -8089,8 +7410,7 @@ bool FakeVimHandler::Private::handleInsertInEditor(const Input &input) return true; } -bool FakeVimHandler::Private::passEventToEditor(QEvent &event, QTextCursor &tc) -{ +bool FakeVimHandler::Private::passEventToEditor(QEvent &event, QTextCursor &tc) { removeEventFilter(); q->requestDisableBlockSelection(); @@ -8098,30 +7418,25 @@ bool FakeVimHandler::Private::passEventToEditor(QEvent &event, QTextCursor &tc) EDITOR(setTextCursor(tc)); bool accepted = QApplication::sendEvent(editor(), &event); - if (!m_textedit && !m_plaintextedit) - return false; + if (!m_textedit && !m_plaintextedit) return false; - if (accepted) - tc = editorCursor(); + if (accepted) tc = editorCursor(); return accepted; } -QString FakeVimHandler::Private::lineContents(int line) const -{ +QString FakeVimHandler::Private::lineContents(int line) const { return document()->findBlockByLineNumber(line - 1).text(); } -QString FakeVimHandler::Private::textAt(int from, int to) const -{ +QString FakeVimHandler::Private::textAt(int from, int to) const { QTextCursor tc(document()); tc.setPosition(from); tc.setPosition(to, KeepAnchor); return tc.selectedText().replace(ParagraphSeparator, '\n'); } -void FakeVimHandler::Private::setLineContents(int line, const QString &contents) -{ +void FakeVimHandler::Private::setLineContents(int line, const QString &contents) { QTextBlock block = document()->findBlockByLineNumber(line - 1); QTextCursor tc = m_cursor; const int begin = block.position(); @@ -8131,9 +7446,8 @@ void FakeVimHandler::Private::setLineContents(int line, const QString &contents) tc.insertText(contents); } -int FakeVimHandler::Private::blockBoundary(const QString &left, - const QString &right, bool closing, int count) const -{ +int FakeVimHandler::Private::blockBoundary(const QString &left, const QString &right, bool closing, + int count) const { const QString &begin = closing ? left : right; const QString &end = closing ? right : left; @@ -8171,81 +7485,59 @@ int FakeVimHandler::Private::blockBoundary(const QString &left, int counter = 0; while (true) { tc2 = document()->find(end, tc2, flags); - if (tc2.isNull()) - return -1; - if (!tc1.isNull()) - tc1 = document()->find(begin, tc1, flags); + if (tc2.isNull()) return -1; + if (!tc1.isNull()) tc1 = document()->find(begin, tc1, flags); while (!tc1.isNull() && (closing ? (tc1 < tc2) : (tc2 < tc1))) { ++level; tc1 = document()->find(begin, tc1, flags); } - while (level > 0 - && (tc1.isNull() || (closing ? (tc2 < tc1) : (tc1 < tc2)))) { + while (level > 0 && (tc1.isNull() || (closing ? (tc2 < tc1) : (tc1 < tc2)))) { --level; tc2 = document()->find(end, tc2, flags); - if (tc2.isNull()) - return -1; + if (tc2.isNull()) return -1; } - if (level == 0 - && (tc1.isNull() || (closing ? (tc2 < tc1) : (tc1 < tc2)))) { + if (level == 0 && (tc1.isNull() || (closing ? (tc2 < tc1) : (tc1 < tc2)))) { ++counter; - if (counter >= count) - break; + if (counter >= count) break; } } return tc2.position() - end.size(); } -int FakeVimHandler::Private::lineNumber(const QTextBlock &block) const -{ - if (block.isVisible()) - return block.firstLineNumber() + 1; +int FakeVimHandler::Private::lineNumber(const QTextBlock &block) const { + if (block.isVisible()) return block.firstLineNumber() + 1; // Folded block has line number of the nearest previous visible line. QTextBlock block2 = block; - while (block2.isValid() && !block2.isVisible()) - block2 = block2.previous(); + while (block2.isValid() && !block2.isVisible()) block2 = block2.previous(); return block2.firstLineNumber() + 1; } -int FakeVimHandler::Private::columnAt(int pos) const -{ - return pos - blockAt(pos).position(); -} +int FakeVimHandler::Private::columnAt(int pos) const { return pos - blockAt(pos).position(); } -int FakeVimHandler::Private::blockNumberAt(int pos) const -{ - return blockAt(pos).blockNumber(); -} +int FakeVimHandler::Private::blockNumberAt(int pos) const { return blockAt(pos).blockNumber(); } -QTextBlock FakeVimHandler::Private::blockAt(int pos) const -{ - return document()->findBlock(pos); -} +QTextBlock FakeVimHandler::Private::blockAt(int pos) const { return document()->findBlock(pos); } -QTextBlock FakeVimHandler::Private::nextLine(const QTextBlock &block) const -{ +QTextBlock FakeVimHandler::Private::nextLine(const QTextBlock &block) const { return blockAt(block.position() + block.length()); } -QTextBlock FakeVimHandler::Private::previousLine(const QTextBlock &block) const -{ +QTextBlock FakeVimHandler::Private::previousLine(const QTextBlock &block) const { return blockAt(block.position() - 1); } -int FakeVimHandler::Private::firstPositionInLine(int line, bool onlyVisibleLines) const -{ +int FakeVimHandler::Private::firstPositionInLine(int line, bool onlyVisibleLines) const { QTextBlock block = onlyVisibleLines ? document()->findBlockByLineNumber(line - 1) - : document()->findBlockByNumber(line - 1); + : document()->findBlockByNumber(line - 1); return block.position(); } -int FakeVimHandler::Private::lastPositionInLine(int line, bool onlyVisibleLines) const -{ +int FakeVimHandler::Private::lastPositionInLine(int line, bool onlyVisibleLines) const { QTextBlock block; if (onlyVisibleLines) { block = document()->findBlockByLineNumber(line - 1); @@ -8254,8 +7546,7 @@ int FakeVimHandler::Private::lastPositionInLine(int line, bool onlyVisibleLines) block = nextLine(block); } while (block.isValid() && !block.isVisible()); if (block.isValid()) { - if (line > 0) - block = block.previous(); + if (line > 0) block = block.previous(); } else { block = document()->lastBlock(); } @@ -8264,23 +7555,19 @@ int FakeVimHandler::Private::lastPositionInLine(int line, bool onlyVisibleLines) } const int position = block.position() + block.length() - 1; - if (block.length() > 1 && !isVisualMode() && !isInsertMode()) - return position - 1; + if (block.length() > 1 && !isVisualMode() && !isInsertMode()) return position - 1; return position; } -int FakeVimHandler::Private::lineForPosition(int pos) const -{ +int FakeVimHandler::Private::lineForPosition(int pos) const { const QTextBlock block = blockAt(pos); - if (!block.isValid()) - return 0; + if (!block.isValid()) return 0; const int positionInBlock = pos - block.position(); const int lineNumberInBlock = block.layout()->lineForTextPosition(positionInBlock).lineNumber(); return block.firstLineNumber() + lineNumberInBlock + 1; } -void FakeVimHandler::Private::toggleVisualMode(VisualMode visualMode) -{ +void FakeVimHandler::Private::toggleVisualMode(VisualMode visualMode) { if (visualMode == g.visualMode) { leaveVisualMode(); } else { @@ -8291,10 +7578,8 @@ void FakeVimHandler::Private::toggleVisualMode(VisualMode visualMode) } } -void FakeVimHandler::Private::leaveVisualMode() -{ - if (!isVisualMode()) - return; +void FakeVimHandler::Private::leaveVisualMode() { + if (!isVisualMode()) return; if (isVisualLineMode()) { g.rangemode = RangeLineMode; @@ -8310,8 +7595,7 @@ void FakeVimHandler::Private::leaveVisualMode() g.visualMode = NoVisualMode; } -void FakeVimHandler::Private::saveLastVisualMode() -{ +void FakeVimHandler::Private::saveLastVisualMode() { if (isVisualMode() && g.mode == CommandMode && g.submode == NoSubMode) { setMark('<', markLessPosition()); setMark('>', markGreaterPosition()); @@ -8320,15 +7604,12 @@ void FakeVimHandler::Private::saveLastVisualMode() } } -QWidget *FakeVimHandler::Private::editor() const -{ - return m_textedit - ? static_cast(m_textedit) - : static_cast(m_plaintextedit); +QWidget *FakeVimHandler::Private::editor() const { + return m_textedit ? static_cast(m_textedit) + : static_cast(m_plaintextedit); } -void FakeVimHandler::Private::joinPreviousEditBlock() -{ +void FakeVimHandler::Private::joinPreviousEditBlock() { UNDO_DEBUG("JOIN"); if (m_buffer->breakEditBlock) { beginEditBlock(); @@ -8346,18 +7627,14 @@ void FakeVimHandler::Private::joinPreviousEditBlock() } } -void FakeVimHandler::Private::beginEditBlock(bool largeEditBlock) -{ +void FakeVimHandler::Private::beginEditBlock(bool largeEditBlock) { UNDO_DEBUG("BEGIN EDIT BLOCK" << m_buffer->editBlockLevel + 1); - if (!largeEditBlock && !m_buffer->undoState.isValid()) - pushUndoState(false); - if (m_buffer->editBlockLevel == 0) - m_buffer->breakEditBlock = true; + if (!largeEditBlock && !m_buffer->undoState.isValid()) pushUndoState(false); + if (m_buffer->editBlockLevel == 0) m_buffer->breakEditBlock = true; ++m_buffer->editBlockLevel; } -void FakeVimHandler::Private::endEditBlock() -{ +void FakeVimHandler::Private::endEditBlock() { UNDO_DEBUG("END EDIT BLOCK" << m_buffer->editBlockLevel); if (m_buffer->editBlockLevel <= 0) { qWarning("beginEditBlock() not called before endEditBlock()!"); @@ -8368,12 +7645,10 @@ void FakeVimHandler::Private::endEditBlock() m_buffer->undo.push(m_buffer->undoState); m_buffer->undoState = State(); } - if (m_buffer->editBlockLevel == 0) - m_buffer->breakEditBlock = false; + if (m_buffer->editBlockLevel == 0) m_buffer->breakEditBlock = false; } -void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved, int charsAdded) -{ +void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved, int charsAdded) { // Record inserted and deleted text in insert mode. if (isInsertMode() && (charsAdded > 0 || charsRemoved > 0) && canModifyBufferData()) { BufferData::InsertState &insertState = m_buffer->insertState; @@ -8394,24 +7669,24 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved, // number of removed characters, assume that the document has been changed // externally and invalidate current insert state. - const bool wholeDocumentChanged = - charsRemoved > 1 - && charsAdded > 0 - && charsAdded + 1 == document()->characterCount(); + const bool wholeDocumentChanged = charsRemoved > 1 && charsAdded > 0 && + charsAdded + 1 == document()->characterCount(); if (position < insertState.pos1) { // const int backspaceCount = insertState.pos1 - position; - if (backspaceCount != charsRemoved || (oldPosition == charsRemoved && wholeDocumentChanged)) { + if (backspaceCount != charsRemoved || + (oldPosition == charsRemoved && wholeDocumentChanged)) { invalidateInsertState(); } else { const QString inserted = textAt(position, oldPosition); const QString removed = insertState.textBeforeCursor.right(backspaceCount); // Ignore backspaces if same text was just inserted. - if ( !inserted.endsWith(removed) ) { + if (!inserted.endsWith(removed)) { insertState.backspaces += backspaceCount; insertState.pos1 = position; - insertState.pos2 = qMax(position, insertState.pos2 - backspaceCount); + insertState.pos2 = + qMax(position, insertState.pos2 - backspaceCount); } } } else if (position + charsRemoved > insertState.pos2) { @@ -8425,8 +7700,7 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved, } else if (charsAdded > 0 && insertState.insertingSpaces) { for (int i = position; i < position + charsAdded; ++i) { const QChar c = characterAt(i); - if (c.unicode() == ' ' || c.unicode() == '\t') - insertState.spaces.insert(i); + if (c.unicode() == ' ' || c.unicode() == '\t') insertState.spaces.insert(i); } } @@ -8436,12 +7710,10 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved, } } - if (!m_highlighted.isEmpty()) - q->highlightMatches(m_highlighted); + if (!m_highlighted.isEmpty()) q->highlightMatches(m_highlighted); } -void FakeVimHandler::Private::onCursorPositionChanged() -{ +void FakeVimHandler::Private::onCursorPositionChanged() { if (!m_inFakeVim) { m_cursorNeedsUpdate = true; @@ -8452,10 +7724,8 @@ void FakeVimHandler::Private::onCursorPositionChanged() } } -void FakeVimHandler::Private::onUndoCommandAdded() -{ - if (!canModifyBufferData()) - return; +void FakeVimHandler::Private::onUndoCommandAdded() { + if (!canModifyBufferData()) return; // Undo commands removed? UNDO_DEBUG("Undo added" << "previous: REV" << m_buffer->lastRevision); @@ -8476,21 +7746,17 @@ void FakeVimHandler::Private::onUndoCommandAdded() m_buffer->undo.push(State()); } -void FakeVimHandler::Private::onInputTimeout() -{ +void FakeVimHandler::Private::onInputTimeout() { enterFakeVim(); EventResult result = handleKey(Input()); leaveFakeVim(result); } -void FakeVimHandler::Private::onFixCursorTimeout() -{ - if (editor()) - fixExternalCursorPosition(editor()->hasFocus() && !isCommandLineMode()); +void FakeVimHandler::Private::onFixCursorTimeout() { + if (editor()) fixExternalCursorPosition(editor()->hasFocus() && !isCommandLineMode()); } -char FakeVimHandler::Private::currentModeCode() const -{ +char FakeVimHandler::Private::currentModeCode() const { if (g.mode == ExMode) return 'c'; else if (isVisualMode()) @@ -8505,8 +7771,7 @@ char FakeVimHandler::Private::currentModeCode() const return 'i'; } -void FakeVimHandler::Private::undoRedo(bool undo) -{ +void FakeVimHandler::Private::undoRedo(bool undo) { UNDO_DEBUG((undo ? "UNDO" : "REDO")); // FIXME: That's only an approximaxtion. The real solution might @@ -8516,12 +7781,13 @@ void FakeVimHandler::Private::undoRedo(bool undo) QStack &stack2 = undo ? m_buffer->redo : m_buffer->undo; State state = m_buffer->undoState.isValid() ? m_buffer->undoState - : !stack.empty() ? stack.pop() : State(); + : !stack.empty() ? stack.pop() + : State(); CursorPosition lastPos(m_cursor); if (undo ? !document()->isUndoAvailable() : !document()->isRedoAvailable()) { - const QString msg = undo ? Tr::tr("Already at oldest change.") - : Tr::tr("Already at newest change."); + const QString msg = + undo ? Tr::tr("Already at oldest change.") : Tr::tr("Already at newest change."); showMessage(MessageInfo, msg); UNDO_DEBUG(msg); return; @@ -8535,7 +7801,8 @@ void FakeVimHandler::Private::undoRedo(bool undo) if (undo) { do { EDITOR(undo()); - } while (document()->isUndoAvailable() && state.revision >= 0 && state.revision < revision()); + } while (document()->isUndoAvailable() && state.revision >= 0 && + state.revision < revision()); } else { do { EDITOR(redo()); @@ -8563,60 +7830,34 @@ void FakeVimHandler::Private::undoRedo(bool undo) stack2.push(state); setTargetColumn(); - if (atEndOfLine()) - moveLeft(); + if (atEndOfLine()) moveLeft(); UNDO_DEBUG((undo ? "UNDONE" : "REDONE")); } -void FakeVimHandler::Private::undo() -{ - undoRedo(true); +void FakeVimHandler::Private::undo() { undoRedo(true); } + +void FakeVimHandler::Private::redo() { undoRedo(false); } + +void FakeVimHandler::Private::updateCursorShape() { + setThinCursor(g.mode == InsertMode || isVisualLineMode() || isVisualBlockMode() || + isCommandLineMode() || !editor()->hasFocus()); } -void FakeVimHandler::Private::redo() -{ - undoRedo(false); -} +void FakeVimHandler::Private::setThinCursor(bool enable) { EDITOR(setOverwriteMode(!enable)); } -void FakeVimHandler::Private::updateCursorShape() -{ - setThinCursor( - g.mode == InsertMode - || isVisualLineMode() - || isVisualBlockMode() - || isCommandLineMode() - || !editor()->hasFocus()); -} +bool FakeVimHandler::Private::hasThinCursor() const { return !EDITOR(overwriteMode()); } -void FakeVimHandler::Private::setThinCursor(bool enable) -{ - EDITOR(setOverwriteMode(!enable)); -} +void FakeVimHandler::Private::enterReplaceMode() { enterInsertOrReplaceMode(ReplaceMode); } -bool FakeVimHandler::Private::hasThinCursor() const -{ - return !EDITOR(overwriteMode()); -} +void FakeVimHandler::Private::enterInsertMode() { enterInsertOrReplaceMode(InsertMode); } -void FakeVimHandler::Private::enterReplaceMode() -{ - enterInsertOrReplaceMode(ReplaceMode); -} - -void FakeVimHandler::Private::enterInsertMode() -{ - enterInsertOrReplaceMode(InsertMode); -} - -void FakeVimHandler::Private::enterInsertOrReplaceMode(Mode mode) -{ +void FakeVimHandler::Private::enterInsertOrReplaceMode(Mode mode) { if (mode != InsertMode && mode != ReplaceMode) { qWarning("Unexpected mode"); return; } - if (g.mode == mode) - return; + if (g.mode == mode) return; g.mode = mode; @@ -8629,8 +7870,7 @@ void FakeVimHandler::Private::enterInsertOrReplaceMode(Mode mode) // Entering insert mode from command mode. if (mode == InsertMode) { // m_targetColumn shouldn't be -1 (end of line). - if (m_targetColumn == -1) - setTargetColumn(); + if (m_targetColumn == -1) setTargetColumn(); } g.submode = NoSubMode; @@ -8640,8 +7880,7 @@ void FakeVimHandler::Private::enterInsertOrReplaceMode(Mode mode) } } -void FakeVimHandler::Private::enterVisualInsertMode(QChar command) -{ +void FakeVimHandler::Private::enterVisualInsertMode(QChar command) { if (isVisualBlockMode()) { bool append = command == 'A'; bool change = command == 's' || command == 'c'; @@ -8651,8 +7890,8 @@ void FakeVimHandler::Private::enterVisualInsertMode(QChar command) const CursorPosition lastAnchor = markLessPosition(); const CursorPosition lastPosition = markGreaterPosition(); CursorPosition pos(lastAnchor.line, - append ? qMax(lastPosition.column, lastAnchor.column) + 1 - : qMin(lastPosition.column, lastAnchor.column)); + append ? qMax(lastPosition.column, lastAnchor.column) + 1 + : qMin(lastPosition.column, lastAnchor.column)); if (append) { m_visualBlockInsert = m_visualTargetColumn == -1 ? AppendToEndOfLineBlockInsertMode @@ -8667,8 +7906,7 @@ void FakeVimHandler::Private::enterVisualInsertMode(QChar command) } setCursorPosition(pos); - if (m_visualBlockInsert == AppendToEndOfLineBlockInsertMode) - moveBehindEndOfLine(); + if (m_visualBlockInsert == AppendToEndOfLineBlockInsertMode) moveBehindEndOfLine(); } else { m_visualBlockInsert = NoneBlockInsertMode; leaveVisualMode(); @@ -8689,21 +7927,17 @@ void FakeVimHandler::Private::enterVisualInsertMode(QChar command) } setAnchor(); - if (m_visualBlockInsert != ChangeBlockInsertMode) - breakEditBlock(); + if (m_visualBlockInsert != ChangeBlockInsertMode) breakEditBlock(); enterInsertMode(); } -void FakeVimHandler::Private::enterCommandMode(Mode returnToMode) -{ - if (g.isRecording && isCommandLineMode()) - record(Input(Key_Escape, NoModifier)); +void FakeVimHandler::Private::enterCommandMode(Mode returnToMode) { + if (g.isRecording && isCommandLineMode()) record(Input(Key_Escape, NoModifier)); if (isNoVisualMode()) { if (atEndOfLine()) { m_cursor.movePosition(Left, KeepAnchor); - if (m_targetColumn != -1) - setTargetColumn(); + if (m_targetColumn != -1) setTargetColumn(); } setAnchor(); } @@ -8715,8 +7949,7 @@ void FakeVimHandler::Private::enterCommandMode(Mode returnToMode) m_anchorPastEnd = false; } -void FakeVimHandler::Private::enterExMode(const QString &contents) -{ +void FakeVimHandler::Private::enterExMode(const QString &contents) { g.currentMessage.clear(); g.commandBuffer.clear(); if (isVisualMode()) @@ -8729,10 +7962,9 @@ void FakeVimHandler::Private::enterExMode(const QString &contents) unfocus(); } -void FakeVimHandler::Private::recordJump(int position) -{ - CursorPosition pos = position >= 0 ? CursorPosition(document(), position) - : CursorPosition(m_cursor); +void FakeVimHandler::Private::recordJump(int position) { + CursorPosition pos = + position >= 0 ? CursorPosition(document(), position) : CursorPosition(m_cursor); setMark('\'', pos); setMark('`', pos); if (m_buffer->jumpListUndo.isEmpty() || m_buffer->jumpListUndo.top() != pos) @@ -8741,10 +7973,9 @@ void FakeVimHandler::Private::recordJump(int position) UNDO_DEBUG("jumps: " << m_buffer->jumpListUndo); } -void FakeVimHandler::Private::jump(int distance) -{ +void FakeVimHandler::Private::jump(int distance) { QStack &from = (distance > 0) ? m_buffer->jumpListRedo : m_buffer->jumpListUndo; - QStack &to = (distance > 0) ? m_buffer->jumpListUndo : m_buffer->jumpListRedo; + QStack &to = (distance > 0) ? m_buffer->jumpListUndo : m_buffer->jumpListRedo; int len = qMin(qAbs(distance), from.size()); CursorPosition m(m_cursor); setMark('\'', m); @@ -8757,8 +7988,7 @@ void FakeVimHandler::Private::jump(int distance) setTargetColumn(); } -Column FakeVimHandler::Private::indentation(const QString &line) const -{ +Column FakeVimHandler::Private::indentation(const QString &line) const { int ts = s.tabStop.value(); int physical = 0; int logical = 0; @@ -8776,19 +8006,14 @@ Column FakeVimHandler::Private::indentation(const QString &line) const return Column(physical, logical); } -QString FakeVimHandler::Private::tabExpand(int n) const -{ +QString FakeVimHandler::Private::tabExpand(int n) const { int ts = s.tabStop.value(); - if (s.expandTab.value() || ts < 1) - return QString(n, ' '); - return QString(n / ts, '\t') - + QString(n % ts, ' '); + if (s.expandTab.value() || ts < 1) return QString(n, ' '); + return QString(n / ts, '\t') + QString(n % ts, ' '); } -void FakeVimHandler::Private::insertAutomaticIndentation(bool goingDown, bool forceAutoIndent) -{ - if (!forceAutoIndent && !s.autoIndent.value() && !s.smartIndent.value()) - return; +void FakeVimHandler::Private::insertAutomaticIndentation(bool goingDown, bool forceAutoIndent) { + if (!forceAutoIndent && !s.autoIndent.value() && !s.smartIndent.value()) return; if (s.smartIndent.value()) { QTextBlock bl = block(); @@ -8799,38 +8024,31 @@ void FakeVimHandler::Private::insertAutomaticIndentation(bool goingDown, bool fo QString text = bl.text(); int pos = 0; int n = text.size(); - while (pos < n && text.at(pos).isSpace()) - ++pos; + while (pos < n && text.at(pos).isSpace()) ++pos; text.truncate(pos); // FIXME: handle 'smartindent' and 'cindent' insertText(text); } } -void FakeVimHandler::Private::handleStartOfLine() -{ - if (s.startOfLine.value()) - moveToFirstNonBlankOnLine(); +void FakeVimHandler::Private::handleStartOfLine() { + if (s.startOfLine.value()) moveToFirstNonBlankOnLine(); } -void FakeVimHandler::Private::replay(const QString &command, int repeat) -{ - if (repeat <= 0) - return; +void FakeVimHandler::Private::replay(const QString &command, int repeat) { + if (repeat <= 0) return; - //qDebug() << "REPLAY: " << quoteUnprintable(command); + // qDebug() << "REPLAY: " << quoteUnprintable(command); clearCurrentMode(); const Inputs inputs(command); for (int i = 0; i < repeat; ++i) { for (const Input &in : inputs) { - if (handleDefaultKey(in) != EventHandled) - return; + if (handleDefaultKey(in) != EventHandled) return; } } } -QString FakeVimHandler::Private::visualDotCommand() const -{ +QString FakeVimHandler::Private::visualDotCommand() const { QTextCursor start(m_cursor); QTextCursor end(start); end.setPosition(end.anchor()); @@ -8847,8 +8065,7 @@ QString FakeVimHandler::Private::visualDotCommand() const return QString(); const int down = qAbs(start.blockNumber() - end.blockNumber()); - if (down != 0) - command.append(QStringLiteral("%1j").arg(down)); + if (down != 0) command.append(QStringLiteral("%1j").arg(down)); const int right = start.positionInBlock() - end.positionInBlock(); if (right != 0) { @@ -8859,8 +8076,7 @@ QString FakeVimHandler::Private::visualDotCommand() const return command; } -void FakeVimHandler::Private::selectTextObject(bool simple, bool inner) -{ +void FakeVimHandler::Private::selectTextObject(bool simple, bool inner) { const int position1 = this->position(); const int anchor1 = this->anchor(); bool setupAnchor = (position1 == anchor1); @@ -8904,8 +8120,8 @@ void FakeVimHandler::Private::selectTextObject(bool simple, bool inner) // select trailing spaces if no leading space QChar afterCursor = characterAt(position() + direction); - if (!leadingSpace && afterCursor.isSpace() && afterCursor != ParagraphSeparator - && !atBlockStart()) { + if (!leadingSpace && afterCursor.isSpace() && afterCursor != ParagraphSeparator && + !atBlockStart()) { if (forward) moveToNextBoundaryEnd(1, simple); else @@ -8917,9 +8133,9 @@ void FakeVimHandler::Private::selectTextObject(bool simple, bool inner) if (setupAnchor && (!characterAtCursor().isSpace() || atBlockEnd())) { int min = block().position(); int pos = anchor(); - while (pos >= min && characterAt(--pos).isSpace()) {} - if (pos >= min) - setAnchorAndPosition(pos + 1, position()); + while (pos >= min && characterAt(--pos).isSpace()) { + } + if (pos >= min) setAnchorAndPosition(pos + 1, position()); } if (i + 1 < repeat) { @@ -8944,23 +8160,13 @@ void FakeVimHandler::Private::selectTextObject(bool simple, bool inner) setTargetColumn(); } -void FakeVimHandler::Private::selectWordTextObject(bool inner) -{ - selectTextObject(false, inner); -} +void FakeVimHandler::Private::selectWordTextObject(bool inner) { selectTextObject(false, inner); } -void FakeVimHandler::Private::selectWORDTextObject(bool inner) -{ - selectTextObject(true, inner); -} +void FakeVimHandler::Private::selectWORDTextObject(bool inner) { selectTextObject(true, inner); } -void FakeVimHandler::Private::selectSentenceTextObject(bool inner) -{ - Q_UNUSED(inner) -} +void FakeVimHandler::Private::selectSentenceTextObject(bool inner) { Q_UNUSED(inner) } -void FakeVimHandler::Private::selectParagraphTextObject(bool inner) -{ +void FakeVimHandler::Private::selectParagraphTextObject(bool inner) { const QTextCursor oldCursor = m_cursor; const VisualMode oldVisualMode = g.visualMode; @@ -8975,8 +8181,7 @@ void FakeVimHandler::Private::selectParagraphTextObject(bool inner) moveToParagraphStartOrEnd(-1); setAnchor(); - if (!isVisualLineMode() && isVisualMode()) - toggleVisualMode(VisualLineMode); + if (!isVisualLineMode() && isVisualMode()) toggleVisualMode(VisualLineMode); } const bool forward = anchor() <= position(); @@ -8987,10 +8192,8 @@ void FakeVimHandler::Private::selectParagraphTextObject(bool inner) moveToParagraphStartOrEnd(d); // If selection already changed, decreate count. - if ((setupAnchor && g.submode != NoSubMode) - || oldVisualMode != g.visualMode - || m_cursor != oldCursor) - { + if ((setupAnchor && g.submode != NoSubMode) || oldVisualMode != g.visualMode || + m_cursor != oldCursor) { --repeat; if (!inner) { moveDown(d); @@ -9001,16 +8204,13 @@ void FakeVimHandler::Private::selectParagraphTextObject(bool inner) if (repeat > 0) { bool isCountEven = repeat % 2 == 0; - bool endsOnParagraph = - inner ? isCountEven == startsAtParagraph : startsAtParagraph; + bool endsOnParagraph = inner ? isCountEven == startsAtParagraph : startsAtParagraph; if (inner) { repeat = repeat / 2; - if (!isCountEven || endsOnParagraph) - ++repeat; + if (!isCountEven || endsOnParagraph) ++repeat; } else { - if (endsOnParagraph) - ++repeat; + if (endsOnParagraph) ++repeat; } if (!moveToNextParagraph(d * repeat)) { @@ -9038,16 +8238,12 @@ void FakeVimHandler::Private::selectParagraphTextObject(bool inner) g.movetype = MoveLineWise; } -bool FakeVimHandler::Private::selectBlockTextObject(bool inner, - QChar left, QChar right) -{ +bool FakeVimHandler::Private::selectBlockTextObject(bool inner, QChar left, QChar right) { int p1 = blockBoundary(left, right, false, count()); - if (p1 == -1) - return false; + if (p1 == -1) return false; int p2 = blockBoundary(left, right, true, count()); - if (p2 == -1) - return false; + if (p2 == -1) return false; g.movetype = MoveExclusive; @@ -9055,26 +8251,21 @@ bool FakeVimHandler::Private::selectBlockTextObject(bool inner, p1 += 1; bool moveStart = characterAt(p1) == ParagraphSeparator; bool moveEnd = isFirstNonBlankOnLine(p2); - if (moveStart) - ++p1; - if (moveEnd) - p2 = blockAt(p2).position() - 1; - if (moveStart && moveEnd) - g.movetype = MoveLineWise; + if (moveStart) ++p1; + if (moveEnd) p2 = blockAt(p2).position() - 1; + if (moveStart && moveEnd) g.movetype = MoveLineWise; } else { p2 += 1; } - if (isVisualMode()) - --p2; + if (isVisualMode()) --p2; setAnchorAndPosition(p1, p2); return true; } -bool FakeVimHandler::Private::changeNumberTextObject(int count) -{ +bool FakeVimHandler::Private::changeNumberTextObject(int count) { const QTextBlock block = this->block(); const QString lineText = block.text(); const int posMin = m_cursor.positionInBlock() + 1; @@ -9084,11 +8275,9 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count) QRegularExpressionMatch match; QRegularExpressionMatchIterator it = re.globalMatch(lineText); while (true) { - if (!it.hasNext()) - return false; + if (!it.hasNext()) return false; match = it.next(); - if (match.capturedEnd() >= posMin) - break; + if (match.capturedEnd() >= posMin) break; } int pos = match.capturedStart(); int len = match.capturedLength(); @@ -9100,8 +8289,8 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count) // parse value bool ok; int base = hex ? 16 : octal ? 8 : 10; - qlonglong value = 0; // decimal value - qlonglong uvalue = 0; // hexadecimal or octal value (only unsigned) + qlonglong value = 0; // decimal value + qlonglong uvalue = 0; // hexadecimal or octal value (only unsigned) if (hex || octal) uvalue = num.toULongLong(&ok, base); else @@ -9128,8 +8317,7 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count) // convert hexadecimal number to upper-case if last letter was upper-case if (hex) { const int lastLetter = num.lastIndexOf(QRegularExpression("[a-fA-F]")); - if (lastLetter != -1 && num[lastLetter].isUpper()) - repl = repl.toUpper(); + if (lastLetter != -1 && num[lastLetter].isUpper()) repl = repl.toUpper(); } // preserve leading zeroes @@ -9146,9 +8334,7 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count) return true; } -bool FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, - const QString "e) -{ +bool FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, const QString "e) { QTextCursor tc = m_cursor; int sz = quote.size(); @@ -9156,26 +8342,22 @@ bool FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, QTextCursor tc2(document()); while (tc2 <= tc) { tc1 = document()->find(quote, tc2); - if (tc1.isNull()) - return false; + if (tc1.isNull()) return false; tc2 = document()->find(quote, tc1); - if (tc2.isNull()) - return false; + if (tc2.isNull()) return false; } int p1 = tc1.position(); int p2 = tc2.position(); if (inner) { p2 = qMax(p1, p2 - sz); - if (characterAt(p1) == ParagraphSeparator) - ++p1; + if (characterAt(p1) == ParagraphSeparator) ++p1; } else { p1 -= sz; p2 -= sz - 1; } - if (isVisualMode()) - --p2; + if (isVisualMode()) --p2; setAnchorAndPosition(p1, p2); g.movetype = MoveExclusive; @@ -9183,8 +8365,7 @@ bool FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, return true; } -bool FakeVimHandler::Private::selectArgumentTextObject(bool inner) -{ +bool FakeVimHandler::Private::selectArgumentTextObject(bool inner) { // We are just interested whether we're currently inside angled brackets, // but selectBlockTextObject also moves the cursor, so set it back to // its original position afterwards @@ -9196,14 +8377,11 @@ bool FakeVimHandler::Private::selectArgumentTextObject(bool inner) QTextCursor tcStart(m_cursor); while (true) { - if (tcStart.atStart()) - return true; + if (tcStart.atStart()) return true; const QChar currentChar = characterAt(tcStart.position()); - if (openAngleBracketCount == 0 - && (currentChar == '(' || currentChar == ',')) - break; + if (openAngleBracketCount == 0 && (currentChar == '(' || currentChar == ',')) break; if (currentChar == '<') openAngleBracketCount--; @@ -9223,9 +8401,8 @@ bool FakeVimHandler::Private::selectArgumentTextObject(bool inner) } const QChar currentChar = characterAt(tcEnd.position()); - if (openAngleBracketCount == 0 - && openParanthesisCount == 0 - && (currentChar == ')' || currentChar == ',')) + if (openAngleBracketCount == 0 && openParanthesisCount == 0 && + (currentChar == ')' || currentChar == ',')) break; if (currentChar == '<') @@ -9237,15 +8414,12 @@ bool FakeVimHandler::Private::selectArgumentTextObject(bool inner) else if (currentChar == ')') openParanthesisCount--; - tcEnd.setPosition(tcEnd.position() + 1); } - if (!inner && characterAt(tcEnd.position()) == ',' && characterAt(tcStart.position()) == '(') { tcEnd.setPosition(tcEnd.position() + 1); - if (characterAt(tcEnd.position()) == ' ') - tcEnd.setPosition(tcEnd.position() + 1); + if (characterAt(tcEnd.position()) == ' ') tcEnd.setPosition(tcEnd.position() + 1); } // Never include the opening paranthesis @@ -9253,12 +8427,10 @@ bool FakeVimHandler::Private::selectArgumentTextObject(bool inner) tcStart.setPosition(tcStart.position() + 1); } else if (inner) { tcStart.setPosition(tcStart.position() + 1); - if (characterAt(tcStart.position()) == ' ') - tcStart.setPosition(tcStart.position() + 1); + if (characterAt(tcStart.position()) == ' ') tcStart.setPosition(tcStart.position() + 1); } - if (isVisualMode()) - tcEnd.setPosition(tcEnd.position() - 1); + if (isVisualMode()) tcEnd.setPosition(tcEnd.position() - 1); g.movetype = MoveExclusive; @@ -9266,31 +8438,25 @@ bool FakeVimHandler::Private::selectArgumentTextObject(bool inner) return true; } -Mark FakeVimHandler::Private::mark(QChar code) const -{ +Mark FakeVimHandler::Private::mark(QChar code) const { if (isVisualMode()) { - if (code == '<') - return CursorPosition(document(), qMin(anchor(), position())); - if (code == '>') - return CursorPosition(document(), qMax(anchor(), position())); + if (code == '<') return CursorPosition(document(), qMin(anchor(), position())); + if (code == '>') return CursorPosition(document(), qMax(anchor(), position())); } - if (code.isUpper()) - return g.marks.value(code); + if (code.isUpper()) return g.marks.value(code); return m_buffer->marks.value(code); } -void FakeVimHandler::Private::setMark(QChar code, CursorPosition position) -{ +void FakeVimHandler::Private::setMark(QChar code, CursorPosition position) { if (code.isUpper()) g.marks[code] = Mark(position, m_currentFileName); else m_buffer->marks[code] = Mark(position); } -bool FakeVimHandler::Private::jumpToMark(QChar mark, bool backTickMode) -{ +bool FakeVimHandler::Private::jumpToMark(QChar mark, bool backTickMode) { Mark m = this->mark(mark); if (!m.isValid()) { showMessage(MessageError, msgMarkNotSet(mark)); @@ -9305,23 +8471,19 @@ bool FakeVimHandler::Private::jumpToMark(QChar mark, bool backTickMode) m_buffer->jumpListUndo.pop(); recordJump(); setCursorPosition(m.position(document())); - if (!backTickMode) - moveToFirstNonBlankOnLine(); - if (g.submode == NoSubMode) - setAnchor(); + if (!backTickMode) moveToFirstNonBlankOnLine(); + if (g.submode == NoSubMode) setAnchor(); setTargetColumn(); return true; } -void FakeVimHandler::Private::updateMarks(const Marks &newMarks) -{ +void FakeVimHandler::Private::updateMarks(const Marks &newMarks) { for (auto it = newMarks.cbegin(), end = newMarks.cend(); it != end; ++it) m_buffer->marks[it.key()] = it.value(); } -RangeMode FakeVimHandler::Private::registerRangeMode(int reg) const -{ +RangeMode FakeVimHandler::Private::registerRangeMode(int reg) const { bool isClipboard; bool isSelection; getRegisterType(®, &isClipboard, &isSelection); @@ -9334,8 +8496,7 @@ RangeMode FakeVimHandler::Private::registerRangeMode(int reg) const const QMimeData *data = clipboard->mimeData(mode); if (data && data->hasFormat(vimMimeText)) { QByteArray bytes = data->data(vimMimeText); - if (bytes.length() > 0) - return static_cast(bytes.at(0)); + if (bytes.length() > 0) return static_cast(bytes.at(0)); } // If register content is clipboard: @@ -9348,25 +8509,20 @@ RangeMode FakeVimHandler::Private::registerRangeMode(int reg) const return g.registers[reg].rangemode; } -void FakeVimHandler::Private::setRegister(int reg, const QString &contents, RangeMode mode) -{ +void FakeVimHandler::Private::setRegister(int reg, const QString &contents, RangeMode mode) { bool copyToClipboard; bool copyToSelection; bool append; getRegisterType(®, ©ToClipboard, ©ToSelection, &append); QString contents2 = contents; - if ((mode == RangeLineMode || mode == RangeLineModeExclusive) - && !contents2.endsWith('\n')) - { + if ((mode == RangeLineMode || mode == RangeLineModeExclusive) && !contents2.endsWith('\n')) { contents2.append('\n'); } if (copyToClipboard || copyToSelection) { - if (copyToClipboard) - setClipboardData(contents2, mode, QClipboard::Clipboard); - if (copyToSelection) - setClipboardData(contents2, mode, QClipboard::Selection); + if (copyToClipboard) setClipboardData(contents2, mode, QClipboard::Clipboard); + if (copyToSelection) setClipboardData(contents2, mode, QClipboard::Selection); } else { if (append) g.registers[reg].contents.append(contents2); @@ -9376,34 +8532,29 @@ void FakeVimHandler::Private::setRegister(int reg, const QString &contents, Rang } } -QString FakeVimHandler::Private::registerContents(int reg) const -{ +QString FakeVimHandler::Private::registerContents(int reg) const { bool copyFromClipboard; bool copyFromSelection; getRegisterType(®, ©FromClipboard, ©FromSelection); if (copyFromClipboard || copyFromSelection) { QClipboard *clipboard = QApplication::clipboard(); - if (copyFromClipboard) - return clipboard->text(QClipboard::Clipboard); - if (copyFromSelection) - return clipboard->text(QClipboard::Selection); + if (copyFromClipboard) return clipboard->text(QClipboard::Clipboard); + if (copyFromSelection) return clipboard->text(QClipboard::Selection); } return g.registers[reg].contents; } -void FakeVimHandler::Private::getRegisterType(int *reg, bool *isClipboard, bool *isSelection, bool *append) const -{ +void FakeVimHandler::Private::getRegisterType(int *reg, bool *isClipboard, bool *isSelection, + bool *append) const { bool clipboard = false; bool selection = false; // If register is uppercase, append content to lower case register on yank/delete. const QChar c(*reg); - if (append != nullptr) - *append = c.isUpper(); - if (c.isUpper()) - *reg = c.toLower().unicode(); + if (append != nullptr) *append = c.isUpper(); + if (c.isUpper()) *reg = c.toLower().unicode(); if (c == '"') { QStringList list = s.clipboard.value().split(','); @@ -9421,10 +8572,8 @@ void FakeVimHandler::Private::getRegisterType(int *reg, bool *isClipboard, bool selection = false; } - if (isClipboard != nullptr) - *isClipboard = clipboard; - if (isSelection != nullptr) - *isSelection = selection; + if (isClipboard != nullptr) *isClipboard = clipboard; + if (isSelection != nullptr) *isSelection = selection; } /////////////////////////////////////////////////////////////////////// @@ -9434,34 +8583,26 @@ void FakeVimHandler::Private::getRegisterType(int *reg, bool *isClipboard, bool /////////////////////////////////////////////////////////////////////// FakeVimHandler::FakeVimHandler(QWidget *widget, QObject *parent) - : QObject(parent), d(new Private(this, widget)) -{} + : QObject(parent), d(new Private(this, widget)) {} -FakeVimHandler::~FakeVimHandler() -{ - delete d; -} +FakeVimHandler::~FakeVimHandler() { delete d; } // gracefully handle that the parent editor is deleted -void FakeVimHandler::disconnectFromEditor() -{ +void FakeVimHandler::disconnectFromEditor() { d->m_textedit = nullptr; d->m_plaintextedit = nullptr; } -void FakeVimHandler::updateGlobalMarksFilenames(const QString &oldFileName, const QString &newFileName) -{ +void FakeVimHandler::updateGlobalMarksFilenames(const QString &oldFileName, + const QString &newFileName) { for (Mark &mark : Private::g.marks) { - if (mark.fileName() == oldFileName) - mark.setFileName(newFileName); + if (mark.fileName() == oldFileName) mark.setFileName(newFileName); } } -bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev) -{ +bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev) { #ifndef FAKEVIM_STANDALONE - if (!fakeVimSettings()->useFakeVim.value()) - return QObject::eventFilter(ob, ev); + if (!fakeVimSettings()->useFakeVim.value()) return QObject::eventFilter(ob, ev); #endif if (ev->type() == QEvent::Shortcut) { @@ -9470,26 +8611,27 @@ bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev) } if (ev->type() == QEvent::KeyPress && - (ob == d->editor() - || (Private::g.mode == ExMode || Private::g.subsubmode == SearchSubSubMode))) { + (ob == d->editor() || + (Private::g.mode == ExMode || Private::g.subsubmode == SearchSubSubMode))) { auto kev = static_cast(ev); KEY_DEBUG("KEYPRESS" << kev->key() << kev->text() << QChar(kev->key())); EventResult res = d->handleEvent(kev); - //if (Private::g.mode == InsertMode) - // completionRequested(); - // returning false core the app see it - //KEY_DEBUG("HANDLED CODE:" << res); - //return res != EventPassedToCore; - //return true; + // if (Private::g.mode == InsertMode) + // completionRequested(); + // returning false core the app see it + // KEY_DEBUG("HANDLED CODE:" << res); + // return res != EventPassedToCore; + // return true; return res == EventHandled || res == EventCancelled; } - if (ev->type() == QEvent::ShortcutOverride && (ob == d->editor() - || (Private::g.mode == ExMode || Private::g.subsubmode == SearchSubSubMode))) { + if (ev->type() == QEvent::ShortcutOverride && + (ob == d->editor() || + (Private::g.mode == ExMode || Private::g.subsubmode == SearchSubSubMode))) { auto kev = static_cast(ev); if (d->wantsOverride(kev)) { KEY_DEBUG("OVERRIDING SHORTCUT" << kev->key()); - ev->accept(); // accepting means "don't run the shortcuts" + ev->accept(); // accepting means "don't run the shortcuts" return true; } KEY_DEBUG("NO SHORTCUT OVERRIDE" << kev->key()); @@ -9501,100 +8643,68 @@ bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev) return false; } - if (ev->type() == QEvent::FocusIn && ob == d->editor()) - d->focus(); + if (ev->type() == QEvent::FocusIn && ob == d->editor()) d->focus(); return QObject::eventFilter(ob, ev); } -void FakeVimHandler::installEventFilter() -{ - d->installEventFilter(); -} +void FakeVimHandler::installEventFilter() { d->installEventFilter(); } -void FakeVimHandler::setupWidget() -{ - d->setupWidget(); -} +void FakeVimHandler::setupWidget() { d->setupWidget(); } -void FakeVimHandler::restoreWidget(int tabSize) -{ - d->restoreWidget(tabSize); -} +void FakeVimHandler::restoreWidget(int tabSize) { d->restoreWidget(tabSize); } -void FakeVimHandler::handleCommand(const QString &cmd) -{ +void FakeVimHandler::handleCommand(const QString &cmd) { d->enterFakeVim(); d->handleCommand(cmd); d->leaveFakeVim(); } -void FakeVimHandler::handleReplay(const QString &keys) -{ +void FakeVimHandler::handleReplay(const QString &keys) { d->enterFakeVim(); d->replay(keys); d->leaveFakeVim(); } -void FakeVimHandler::handleInput(const QString &keys) -{ +void FakeVimHandler::handleInput(const QString &keys) { const Inputs inputs(keys); d->enterFakeVim(); - for (const Input &input : inputs) - d->handleKey(input); + for (const Input &input : inputs) d->handleKey(input); d->leaveFakeVim(); } -void FakeVimHandler::enterCommandMode() -{ - d->enterCommandMode(); -} +void FakeVimHandler::enterCommandMode() { d->enterCommandMode(); } -void FakeVimHandler::setCurrentFileName(const QString &fileName) -{ +void FakeVimHandler::setCurrentFileName(const QString &fileName) { d->m_currentFileName = fileName; } -QString FakeVimHandler::currentFileName() const -{ - return d->m_currentFileName; -} +QString FakeVimHandler::currentFileName() const { return d->m_currentFileName; } -void FakeVimHandler::showMessage(MessageLevel level, const QString &msg) -{ +void FakeVimHandler::showMessage(MessageLevel level, const QString &msg) { d->showMessage(level, msg); } -QWidget *FakeVimHandler::widget() -{ - return d->editor(); -} +QWidget *FakeVimHandler::widget() { return d->editor(); } // Test only -int FakeVimHandler::physicalIndentation(const QString &line) const -{ +int FakeVimHandler::physicalIndentation(const QString &line) const { Column ind = d->indentation(line); return ind.physical; } -int FakeVimHandler::logicalIndentation(const QString &line) const -{ +int FakeVimHandler::logicalIndentation(const QString &line) const { Column ind = d->indentation(line); return ind.logical; } -QString FakeVimHandler::tabExpand(int n) const -{ - return d->tabExpand(n); -} +QString FakeVimHandler::tabExpand(int n) const { return d->tabExpand(n); } -void FakeVimHandler::miniBufferTextEdited(const QString &text, int cursorPos, int anchorPos) -{ +void FakeVimHandler::miniBufferTextEdited(const QString &text, int cursorPos, int anchorPos) { d->miniBufferTextEdited(text, cursorPos, anchorPos); } -void FakeVimHandler::setTextCursorPosition(int position) -{ +void FakeVimHandler::setTextCursorPosition(int position) { int pos = qMax(0, qMin(position, d->lastPositionInDocument())); if (d->isVisualMode()) d->setPosition(pos); @@ -9602,26 +8712,18 @@ void FakeVimHandler::setTextCursorPosition(int position) d->setAnchorAndPosition(pos, pos); d->setTargetColumn(); - if (!d->m_inFakeVim) - d->commitCursor(); + if (!d->m_inFakeVim) d->commitCursor(); } -QTextCursor FakeVimHandler::textCursor() const -{ - return d->m_cursor; -} +QTextCursor FakeVimHandler::textCursor() const { return d->m_cursor; } -void FakeVimHandler::setTextCursor(const QTextCursor &cursor) -{ - d->m_cursor = cursor; -} +void FakeVimHandler::setTextCursor(const QTextCursor &cursor) { d->m_cursor = cursor; } -bool FakeVimHandler::jumpToLocalMark(QChar mark, bool backTickMode) -{ +bool FakeVimHandler::jumpToLocalMark(QChar mark, bool backTickMode) { return d->jumpToMark(mark, backTickMode); } -} // namespace Internal -} // namespace FakeVim +} // namespace Internal +} // namespace FakeVim Q_DECLARE_METATYPE(FakeVim::Internal::FakeVimHandler::Private::BufferDataPtr) diff --git a/src/libraries/fakevim/fakevim/fakevimhandler.h b/src/libraries/fakevim/fakevim/fakevimhandler.h index 75992d86b..4942417fe 100644 --- a/src/libraries/fakevim/fakevim/fakevimhandler.h +++ b/src/libraries/fakevim/fakevim/fakevimhandler.h @@ -28,31 +28,28 @@ #define FAKEVIM_STANDALONE #ifdef FAKEVIM_STANDALONE -//# include "private/fakevim_export.h" +// # include "private/fakevim_export.h" #endif #include #include - #include #include namespace FakeVim { namespace Internal { -enum RangeMode -{ +enum RangeMode { // Reordering first three enum items here will break // compatibility with clipboard format stored by Vim. - RangeCharMode, // v - RangeLineMode, // V - RangeBlockMode, // Ctrl-v + RangeCharMode, // v + RangeLineMode, // V + RangeBlockMode, // Ctrl-v RangeLineModeExclusive, - RangeBlockAndTailMode // Ctrl-v for D and X + RangeBlockAndTailMode // Ctrl-v for D and X }; -struct Range -{ +struct Range { Range() = default; Range(int b, int e, RangeMode m = RangeCharMode); QString toString() const; @@ -63,11 +60,9 @@ struct Range RangeMode rangemode = RangeCharMode; }; -struct ExCommand -{ +struct ExCommand { ExCommand() = default; - ExCommand(const QString &cmd, const QString &args = QString(), - const Range &range = Range()); + ExCommand(const QString &cmd, const QString &args = QString(), const Range &range = Range()); bool matches(const QString &min, const QString &full) const; @@ -79,40 +74,35 @@ struct ExCommand }; // message levels sorted by severity -enum MessageLevel -{ - MessageMode, // show current mode (format "-- %1 --") - MessageCommand, // show last Ex command or search - MessageInfo, // result of a command - MessageWarning, // warning - MessageError, // error - MessageShowCmd // partial command +enum MessageLevel { + MessageMode, // show current mode (format "-- %1 --") + MessageCommand, // show last Ex command or search + MessageInfo, // result of a command + MessageWarning, // warning + MessageError, // error + MessageShowCmd // partial command }; template -class Signal -{ -public: +class Signal { + public: using Callable = std::function; void connect(const Callable &callable) { m_callables.push_back(callable); } - template - void operator()(Args ...args) const - { - for (const Callable &callable : m_callables) - callable(args...); - } + template + void operator()(Args... args) const { + for (const Callable &callable : m_callables) callable(args...); + } -private: + private: std::vector m_callables; }; -class FakeVimHandler : public QObject -{ +class FakeVimHandler : public QObject { Q_OBJECT -public: + public: explicit FakeVimHandler(QWidget *widget, QObject *parent = nullptr); ~FakeVimHandler() override; @@ -123,7 +113,7 @@ public: static void updateGlobalMarksFilenames(const QString &oldFileName, const QString &newFileName); -public: + public: void setCurrentFileName(const QString &fileName); QString currentFileName() const; @@ -159,11 +149,12 @@ public: bool eventFilter(QObject *ob, QEvent *ev) override; - Signal commandBufferChanged; + Signal + commandBufferChanged; Signal statusDataChanged; Signal extraInformationChanged; Signal &selection)> selectionChanged; - Signal highlightMatches; + Signal highlightMatches; Signal moveToMatchingParenthesis; Signal checkForElectricCharacter; Signal indentRegion; @@ -186,14 +177,14 @@ public: Signal tabPreviousRequested; Signal tabNextRequested; -public: + public: class Private; -private: + private: Private *d; }; -} // namespace Internal -} // namespace FakeVim +} // namespace Internal +} // namespace FakeVim Q_DECLARE_METATYPE(FakeVim::Internal::ExCommand) diff --git a/src/libraries/fakevim/fakevim/fakevimtr.h b/src/libraries/fakevim/fakevim/fakevimtr.h index cb6f2b47e..3c0688550 100644 --- a/src/libraries/fakevim/fakevim/fakevimtr.h +++ b/src/libraries/fakevim/fakevim/fakevimtr.h @@ -29,9 +29,8 @@ namespace FakeVim { -struct Tr -{ +struct Tr { Q_DECLARE_TR_FUNCTIONS(FakeVim) }; -} // namespace FakeVim +} // namespace FakeVim diff --git a/src/libraries/fakevim/fakevim/utils/hostosinfo.cpp b/src/libraries/fakevim/fakevim/utils/hostosinfo.cpp index d4f811b21..3acfb429c 100644 --- a/src/libraries/fakevim/fakevim/utils/hostosinfo.cpp +++ b/src/libraries/fakevim/fakevim/utils/hostosinfo.cpp @@ -32,13 +32,11 @@ using namespace Utils; Qt::CaseSensitivity HostOsInfo::m_overrideFileNameCaseSensitivity = Qt::CaseSensitive; bool HostOsInfo::m_useOverrideFileNameCaseSensitivity = false; -void HostOsInfo::setOverrideFileNameCaseSensitivity(Qt::CaseSensitivity sensitivity) -{ +void HostOsInfo::setOverrideFileNameCaseSensitivity(Qt::CaseSensitivity sensitivity) { m_useOverrideFileNameCaseSensitivity = true; m_overrideFileNameCaseSensitivity = sensitivity; } -void HostOsInfo::unsetOverrideFileNameCaseSensitivity() -{ +void HostOsInfo::unsetOverrideFileNameCaseSensitivity() { m_useOverrideFileNameCaseSensitivity = false; } diff --git a/src/libraries/fakevim/fakevim/utils/hostosinfo.h b/src/libraries/fakevim/fakevim/utils/hostosinfo.h index 4cd8f4a6c..e2bf03fd0 100644 --- a/src/libraries/fakevim/fakevim/utils/hostosinfo.h +++ b/src/libraries/fakevim/fakevim/utils/hostosinfo.h @@ -25,23 +25,21 @@ #pragma once -#include "osspecificaspects.h" - #include +#include "osspecificaspects.h" + #ifdef Q_OS_WIN #define QTC_HOST_EXE_SUFFIX QTC_WIN_EXE_SUFFIX #else #define QTC_HOST_EXE_SUFFIX "" -#endif // Q_OS_WIN +#endif // Q_OS_WIN namespace Utils { -class HostOsInfo -{ -public: - static constexpr OsType hostOs() - { +class HostOsInfo { + public: + static constexpr OsType hostOs() { #if defined(Q_OS_WIN) return OsTypeWindows; #elif defined(Q_OS_LINUX) @@ -58,8 +56,7 @@ public: static constexpr bool isWindowsHost() { return hostOs() == OsTypeWindows; } static constexpr bool isLinuxHost() { return hostOs() == OsTypeLinux; } static constexpr bool isMacHost() { return hostOs() == OsTypeMac; } - static constexpr bool isAnyUnixHost() - { + static constexpr bool isAnyUnixHost() { #ifdef Q_OS_UNIX return true; #else @@ -67,34 +64,28 @@ public: #endif } - static QString withExecutableSuffix(const QString &executable) - { + static QString withExecutableSuffix(const QString &executable) { return OsSpecificAspects::withExecutableSuffix(hostOs(), executable); } static void setOverrideFileNameCaseSensitivity(Qt::CaseSensitivity sensitivity); static void unsetOverrideFileNameCaseSensitivity(); - static Qt::CaseSensitivity fileNameCaseSensitivity() - { + static Qt::CaseSensitivity fileNameCaseSensitivity() { return m_useOverrideFileNameCaseSensitivity - ? m_overrideFileNameCaseSensitivity - : OsSpecificAspects::fileNameCaseSensitivity(hostOs()); + ? m_overrideFileNameCaseSensitivity + : OsSpecificAspects::fileNameCaseSensitivity(hostOs()); } - static QChar pathListSeparator() - { - return OsSpecificAspects::pathListSeparator(hostOs()); - } + static QChar pathListSeparator() { return OsSpecificAspects::pathListSeparator(hostOs()); } - static Qt::KeyboardModifier controlModifier() - { + static Qt::KeyboardModifier controlModifier() { return OsSpecificAspects::controlModifier(hostOs()); } -private: + private: static Qt::CaseSensitivity m_overrideFileNameCaseSensitivity; static bool m_useOverrideFileNameCaseSensitivity; }; -} // namespace Utils +} // namespace Utils diff --git a/src/libraries/fakevim/fakevim/utils/optional.h b/src/libraries/fakevim/fakevim/utils/optional.h index 5e9aa4a1d..199429523 100644 --- a/src/libraries/fakevim/fakevim/utils/optional.h +++ b/src/libraries/fakevim/fakevim/utils/optional.h @@ -83,17 +83,15 @@ using std::experimental::in_place; // TODO: make_optional is a copy, since there is no sensible way to import functions in C++ template -constexpr optional::type> make_optional(T&& v) -{ - return optional::type>(std::experimental::constexpr_forward(v)); +constexpr optional::type> make_optional(T&& v) { + return optional::type>(std::experimental::constexpr_forward(v)); } template -constexpr optional make_optional(std::reference_wrapper v) -{ - return optional(v.get()); +constexpr optional make_optional(std::reference_wrapper v) { + return optional(v.get()); } -} // Utils +} // namespace Utils -//#endif +// #endif diff --git a/src/libraries/fakevim/fakevim/utils/osspecificaspects.h b/src/libraries/fakevim/fakevim/utils/osspecificaspects.h index 54e80e593..1cb5f6db9 100644 --- a/src/libraries/fakevim/fakevim/utils/osspecificaspects.h +++ b/src/libraries/fakevim/fakevim/utils/osspecificaspects.h @@ -36,33 +36,27 @@ enum OsType { OsTypeWindows, OsTypeLinux, OsTypeMac, OsTypeOtherUnix, OsTypeOthe namespace OsSpecificAspects { -inline QString withExecutableSuffix(OsType osType, const QString &executable) -{ +inline QString withExecutableSuffix(OsType osType, const QString &executable) { QString finalName = executable; - if (osType == OsTypeWindows) - finalName += QLatin1String(QTC_WIN_EXE_SUFFIX); + if (osType == OsTypeWindows) finalName += QLatin1String(QTC_WIN_EXE_SUFFIX); return finalName; } -inline Qt::CaseSensitivity fileNameCaseSensitivity(OsType osType) -{ +inline Qt::CaseSensitivity fileNameCaseSensitivity(OsType osType) { return osType == OsTypeWindows || osType == OsTypeMac ? Qt::CaseInsensitive : Qt::CaseSensitive; } -inline Qt::CaseSensitivity envVarCaseSensitivity(OsType osType) -{ +inline Qt::CaseSensitivity envVarCaseSensitivity(OsType osType) { return fileNameCaseSensitivity(osType); } -inline QChar pathListSeparator(OsType osType) -{ +inline QChar pathListSeparator(OsType osType) { return QLatin1Char(osType == OsTypeWindows ? ';' : ':'); } -inline Qt::KeyboardModifier controlModifier(OsType osType) -{ +inline Qt::KeyboardModifier controlModifier(OsType osType) { return osType == OsTypeMac ? Qt::MetaModifier : Qt::ControlModifier; } -} // namespace OsSpecificAspects -} // namespace Utils +} // namespace OsSpecificAspects +} // namespace Utils diff --git a/src/libraries/fakevim/fakevim/utils/qtcassert.cpp b/src/libraries/fakevim/fakevim/utils/qtcassert.cpp index 1b6c87e6c..fdc101d2e 100644 --- a/src/libraries/fakevim/fakevim/utils/qtcassert.cpp +++ b/src/libraries/fakevim/fakevim/utils/qtcassert.cpp @@ -29,8 +29,7 @@ namespace Utils { -void writeAssertLocation(const char *msg) -{ +void writeAssertLocation(const char *msg) { static bool goBoom = qEnvironmentVariableIsSet("QTC_FATAL_ASSERTS"); if (goBoom) qFatal("SOFT ASSERT made fatal: %s", msg); @@ -38,4 +37,4 @@ void writeAssertLocation(const char *msg) qDebug("SOFT ASSERT: %s", msg); } -} // namespace Utils +} // namespace Utils diff --git a/src/libraries/fakevim/fakevim/utils/qtcassert.h b/src/libraries/fakevim/fakevim/utils/qtcassert.h index d2d8b556b..47d4ff017 100644 --- a/src/libraries/fakevim/fakevim/utils/qtcassert.h +++ b/src/libraries/fakevim/fakevim/utils/qtcassert.h @@ -25,16 +25,32 @@ #pragma once -namespace Utils { void writeAssertLocation(const char *msg); } +namespace Utils { +void writeAssertLocation(const char *msg); +} #define QTC_ASSERT_STRINGIFY_HELPER(x) #x #define QTC_ASSERT_STRINGIFY(x) QTC_ASSERT_STRINGIFY_HELPER(x) -#define QTC_ASSERT_STRING(cond) ::Utils::writeAssertLocation(\ - "\"" cond"\" in file " __FILE__ ", line " QTC_ASSERT_STRINGIFY(__LINE__)) +#define QTC_ASSERT_STRING(cond) \ + ::Utils::writeAssertLocation("\"" cond "\" in file " __FILE__ \ + ", line " QTC_ASSERT_STRINGIFY(__LINE__)) // The 'do {...} while (0)' idiom is not used for the main block here to be // able to use 'break' and 'continue' as 'actions'. -#define QTC_ASSERT(cond, action) if (Q_LIKELY(cond)) {} else { QTC_ASSERT_STRING(#cond); action; } do {} while (0) -#define QTC_CHECK(cond) if (Q_LIKELY(cond)) {} else { QTC_ASSERT_STRING(#cond); } do {} while (0) +#define QTC_ASSERT(cond, action) \ + if (Q_LIKELY(cond)) { \ + } else { \ + QTC_ASSERT_STRING(#cond); \ + action; \ + } \ + do { \ + } while (0) +#define QTC_CHECK(cond) \ + if (Q_LIKELY(cond)) { \ + } else { \ + QTC_ASSERT_STRING(#cond); \ + } \ + do { \ + } while (0) #define QTC_GUARD(cond) ((Q_LIKELY(cond)) ? true : (QTC_ASSERT_STRING(#cond), false)) diff --git a/src/libraries/fakevim/utils/test.cpp b/src/libraries/fakevim/utils/test.cpp index 445e6be0f..e3ec25735 100644 --- a/src/libraries/fakevim/utils/test.cpp +++ b/src/libraries/fakevim/utils/test.cpp @@ -2,14 +2,14 @@ #include class SomeClass { -public: + public: SomeClass(const std::string &var) : m_var(var) {} -private: + + private: std::string m_var; }; -int main(int argc, const char *argv[]) -{ +int main(int argc, const char *argv[]) { using namespace std; cout << "TESTING..."; cout << "1"; diff --git a/src/libraries/fuzzy/kfuzzymatcher.cpp b/src/libraries/fuzzy/kfuzzymatcher.cpp index fbee4cc84..57b476a32 100644 --- a/src/libraries/fuzzy/kfuzzymatcher.cpp +++ b/src/libraries/fuzzy/kfuzzymatcher.cpp @@ -21,10 +21,7 @@ using String = QString; * Custom toLower function which is much faster than * c.toLower() directly */ -static inline QChar toLower(QChar c) -{ - return c.isLower() ? c : c.toLower(); -} +static inline QChar toLower(QChar c) { return c.isLower() ? c : c.toLower(); } // internal // clang-format off @@ -191,8 +188,8 @@ static bool match_recursive(String::const_iterator pattern, } // clang-format on -static bool match_internal(StringType pattern, StringType str, int &outScore, unsigned char *matches) -{ +static bool match_internal(StringType pattern, StringType str, int &outScore, + unsigned char *matches) { if (pattern.isEmpty()) { return true; } @@ -204,14 +201,13 @@ static bool match_internal(StringType pattern, StringType str, int &outScore, un const auto patternEnd = pattern.cend(); const auto strEnd = str.cend(); - return match_recursive(patternIt, strIt, outScore, strIt, strEnd, patternEnd, - nullptr, matches, 0, recursionCount); + return match_recursive(patternIt, strIt, outScore, strIt, strEnd, patternEnd, nullptr, matches, + 0, recursionCount); } /**************************************************************/ -bool KFuzzyMatcher::matchSimple(StringType pattern, StringType str) -{ +bool KFuzzyMatcher::matchSimple(StringType pattern, StringType str) { auto patternIt = pattern.cbegin(); for (auto strIt = str.cbegin(); strIt != str.cend() && patternIt != pattern.cend(); ++strIt) { if (strIt->toLower() == patternIt->toLower()) { @@ -221,8 +217,7 @@ bool KFuzzyMatcher::matchSimple(StringType pattern, StringType str) return patternIt == pattern.cend(); } -KFuzzyMatcher::Result KFuzzyMatcher::match(StringType pattern, StringType str) -{ +KFuzzyMatcher::Result KFuzzyMatcher::match(StringType pattern, StringType str) { uint8_t matches[256]; int score = 0; const bool matched = match_internal(pattern, str, score, matches); @@ -232,12 +227,9 @@ KFuzzyMatcher::Result KFuzzyMatcher::match(StringType pattern, StringType str) return result; } - -QString KFuzzyMatcher::toFuzzyMatchedDisplayString(const QString &pattern, - const QString &str, +QString KFuzzyMatcher::toFuzzyMatchedDisplayString(const QString &pattern, const QString &str, const QString &htmlTag, - const QString &htmlTagClose) -{ + const QString &htmlTagClose) { if (pattern.isEmpty()) { return str; } @@ -254,7 +246,7 @@ QString KFuzzyMatcher::toFuzzyMatchedDisplayString(const QString &pattern, QString string = str; int offset = 0; for (int i = 0; i < 256; ++i) { - if (matches[i] == 255){ + if (matches[i] == 255) { break; } string.insert(matches[i] + offset, htmlTag); @@ -263,5 +255,4 @@ QString KFuzzyMatcher::toFuzzyMatchedDisplayString(const QString &pattern, offset += htmlTagClose.size(); } return string; - } diff --git a/src/libraries/fuzzy/kfuzzymatcher.h b/src/libraries/fuzzy/kfuzzymatcher.h index 9e015aff5..91dadd633 100644 --- a/src/libraries/fuzzy/kfuzzymatcher.h +++ b/src/libraries/fuzzy/kfuzzymatcher.h @@ -74,14 +74,12 @@ using StringType = const QString&; * @short Namespace for fuzzy matching of strings * @author Waqar Ahmed */ -namespace KFuzzyMatcher -{ +namespace KFuzzyMatcher { /** * @brief The result of a fuzzy match */ -struct Result -{ +struct Result { /** Score of this match. This can be negative. if matched is @c false then the score will be zero. */ @@ -126,9 +124,7 @@ bool matchSimple(StringType pattern, StringType str); */ Result match(StringType pattern, StringType str); -QString toFuzzyMatchedDisplayString(const QString& pattern, - const QString& str, - const QString& htmlTag, - const QString& htmlTagClose); +QString toFuzzyMatchedDisplayString(const QString& pattern, const QString& str, + const QString& htmlTag, const QString& htmlTagClose); -} // namespace KFuzzyMatcher +} // namespace KFuzzyMatcher diff --git a/src/libraries/qlitehtml/CMakeLists.txt b/src/libraries/qlitehtml/CMakeLists.txt index 68a279c4c..ecb68d59a 100644 --- a/src/libraries/qlitehtml/CMakeLists.txt +++ b/src/libraries/qlitehtml/CMakeLists.txt @@ -1,5 +1,8 @@ cmake_minimum_required(VERSION 3.7) -project(qlitehtml VERSION 1.0 LANGUAGES CXX) +project( + qlitehtml + VERSION 1.0 + LANGUAGES CXX) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) @@ -13,23 +16,29 @@ set(QLITEHTML_DEVEL_COMPONENT Devel) set(QLITEHTML_DEVEL_EXCLUDE_FROM_ALL NO) if(UNIX OR MINGW) - include(GNUInstallDirs) - set(QLITEHTML_BIN_PATH ${CMAKE_INSTALL_BINDIR}) - set(QLITEHTML_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR}) - set(QLITEHTML_HEADER_PATH ${CMAKE_INSTALL_INCLUDEDIR}/qlitehtml) + include(GNUInstallDirs) + set(QLITEHTML_BIN_PATH ${CMAKE_INSTALL_BINDIR}) + set(QLITEHTML_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR}) + set(QLITEHTML_HEADER_PATH ${CMAKE_INSTALL_INCLUDEDIR}/qlitehtml) else() - set(QLITEHTML_BIN_PATH bin) - set(QLITEHTML_LIBRARY_PATH lib) - set(QLITEHTML_HEADER_PATH include/qlitehtml) + set(QLITEHTML_BIN_PATH bin) + set(QLITEHTML_LIBRARY_PATH lib) + set(QLITEHTML_HEADER_PATH include/qlitehtml) endif() -find_package(QT 5.11 NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED) +find_package( + QT 5.11 NAMES Qt6 Qt5 + COMPONENTS Widgets + REQUIRED) +find_package( + Qt${QT_VERSION_MAJOR} + COMPONENTS Widgets + REQUIRED) set(Qt Qt${QT_VERSION_MAJOR}) set(QLITEHTML_BUILD_TESTS OFF) -if (QLITEHTML_BUILD_TESTS) - add_subdirectory(tests/manual/browser) +if(QLITEHTML_BUILD_TESTS) + add_subdirectory(tests/manual/browser) endif() add_subdirectory(src) diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/CMakeLists.txt b/src/libraries/qlitehtml/src/3rdparty/litehtml/CMakeLists.txt index 92d2b74f8..354d11101 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/CMakeLists.txt +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/CMakeLists.txt @@ -4,13 +4,13 @@ project(litehtml LANGUAGES C CXX) include(CTest) enable_testing() -# Soname -# MAJOR is incremented when symbols are removed or changed in an incompatible way -# MINOR is incremented when new symbols are added +# Soname MAJOR is incremented when symbols are removed or changed in an +# incompatible way MINOR is incremented when new symbols are added set(PROJECT_MAJOR 0) set(PROJECT_MINOR 0) -option(EXTERNAL_GUMBO "Link against external gumbo instead of shipping a bundled copy" OFF) +option(EXTERNAL_GUMBO + "Link against external gumbo instead of shipping a bundled copy" OFF) if(WIN32) option(EXTERNAL_XXD "Use external xxd" OFF) else() @@ -18,7 +18,7 @@ else() endif() if(NOT EXTERNAL_GUMBO) -add_subdirectory(src/gumbo) + add_subdirectory(src/gumbo) endif() set(SOURCE_LITEHTML @@ -64,8 +64,7 @@ set(SOURCE_LITEHTML src/utf8_strings.cpp src/web_color.cpp src/num_cvt.cpp - src/strtod.cpp -) + src/strtod.cpp) set(HEADER_LITEHTML include/litehtml.h @@ -116,8 +115,7 @@ set(HEADER_LITEHTML include/litehtml/url_path.h include/litehtml/utf8_strings.h include/litehtml/web_color.h - include/litehtml/num_cvt.h -) + include/litehtml/num_cvt.h) set(TEST_LITEHTML containers/test/container_test.cpp @@ -130,30 +128,32 @@ set(TEST_LITEHTML test/tstring_view_test.cpp test/url_test.cpp test/url_path_test.cpp - test/webColorTest.cpp -) + test/webColorTest.cpp) set(PROJECT_LIB_VERSION ${PROJECT_MAJOR}.${PROJECT_MINOR}.0) set(PROJECT_SO_VERSION ${PROJECT_MAJOR}) add_library(${PROJECT_NAME} ${SOURCE_LITEHTML}) -set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_LIB_VERSION} SOVERSION ${PROJECT_SO_VERSION}) +set_target_properties( + ${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_LIB_VERSION} + SOVERSION ${PROJECT_SO_VERSION}) -set_target_properties(${PROJECT_NAME} PROPERTIES - CXX_STANDARD 11 - C_STANDARD 99 - PUBLIC_HEADER "${HEADER_LITEHTML}" -) +set_target_properties( + ${PROJECT_NAME} + PROPERTIES CXX_STANDARD 11 + C_STANDARD 99 + PUBLIC_HEADER "${HEADER_LITEHTML}") # Export litehtml includes. -target_include_directories(${PROJECT_NAME} PUBLIC - $ - $ - $) +target_include_directories( + ${PROJECT_NAME} + PUBLIC $ + $ + $) target_include_directories(${PROJECT_NAME} PRIVATE include/${PROJECT_NAME}) option(LITEHTML_UTF8 "Build litehtml with UTF-8 text conversion functions." OFF) -if (LITEHTML_UTF8) +if(LITEHTML_UTF8) target_compile_definitions(${PROJECT_NAME} PUBLIC LITEHTML_UTF8) endif() @@ -161,96 +161,94 @@ endif() target_link_libraries(${PROJECT_NAME} PUBLIC gumbo) # install and export -install(TARGETS ${PROJECT_NAME} - EXPORT litehtmlTargets - RUNTIME DESTINATION bin COMPONENT libraries - ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT libraries - LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT libraries - PUBLIC_HEADER DESTINATION include/litehtml -) -install(FILES cmake/litehtmlConfig.cmake DESTINATION lib${LIB_SUFFIX}/cmake/litehtml) -install(EXPORT litehtmlTargets FILE litehtmlTargets.cmake DESTINATION lib${LIB_SUFFIX}/cmake/litehtml) +install( + TARGETS ${PROJECT_NAME} + EXPORT litehtmlTargets + RUNTIME DESTINATION bin COMPONENT libraries + ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT libraries + LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT libraries + PUBLIC_HEADER DESTINATION include/litehtml) +install(FILES cmake/litehtmlConfig.cmake + DESTINATION lib${LIB_SUFFIX}/cmake/litehtml) +install( + EXPORT litehtmlTargets + FILE litehtmlTargets.cmake + DESTINATION lib${LIB_SUFFIX}/cmake/litehtml) # Binary Master.css -if (NOT EXTERNAL_XXD) - add_executable(xxd xxd/xxd.c) - set(XXD_COMMAND $) +if(NOT EXTERNAL_XXD) + add_executable(xxd xxd/xxd.c) + set(XXD_COMMAND $) else() - find_program(XXD_COMMAND xxd) + find_program(XXD_COMMAND xxd) endif() if(WIN32) - file(TO_NATIVE_PATH ${XXD_COMMAND} XXD_COMMAND) - file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include/master.css MASTER_FILE) - add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc - COMMAND type ${MASTER_FILE} | "${XXD_COMMAND}" -i > ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc) + file(TO_NATIVE_PATH ${XXD_COMMAND} XXD_COMMAND) + file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include/master.css + MASTER_FILE) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc + COMMAND type ${MASTER_FILE} | "${XXD_COMMAND}" -i > + ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc) else() - add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc - COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/include/master.css | xxd -i > ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc + COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/include/master.css | xxd -i > + ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc) endif() -set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc PROPERTIES GENERATED TRUE) +set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc + PROPERTIES GENERATED TRUE) # Tests set(BUILD_TESTING OFF) -if (BUILD_TESTING) - include(FetchContent) - FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip - ) - # For Windows: Prevent overriding the parent project's compiler/linker settings - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - FetchContent_GetProperties(googletest) - if(NOT googletest_POPULATED) - FetchContent_Populate(googletest) - add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) - endif() +if(BUILD_TESTING) + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip + ) + # For Windows: Prevent overriding the parent project's compiler/linker + # settings + set(gtest_force_shared_crt + ON + CACHE BOOL "" FORCE) + FetchContent_GetProperties(googletest) + if(NOT googletest_POPULATED) + FetchContent_Populate(googletest) + add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) + endif() - enable_testing() + enable_testing() - set(TEST_NAME ${PROJECT_NAME}_tests) + set(TEST_NAME ${PROJECT_NAME}_tests) - add_executable( - ${TEST_NAME} - ${TEST_LITEHTML} - ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc - ) + add_executable(${TEST_NAME} ${TEST_LITEHTML} + ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc) - set_target_properties(${TEST_NAME} PROPERTIES - CXX_STANDARD 11 - C_STANDARD 99 - PUBLIC_HEADER "${HEADER_LITEHTML}" - ) + set_target_properties( + ${TEST_NAME} + PROPERTIES CXX_STANDARD 11 + C_STANDARD 99 + PUBLIC_HEADER "${HEADER_LITEHTML}") - target_include_directories( - ${TEST_NAME} - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/containers - ) + target_include_directories(${TEST_NAME} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/containers) - target_link_libraries( - ${TEST_NAME} - ${PROJECT_NAME} - gtest_main - ) + target_link_libraries(${TEST_NAME} ${PROJECT_NAME} gtest_main) - include(GoogleTest) - gtest_discover_tests(${TEST_NAME}) + include(GoogleTest) + gtest_discover_tests(${TEST_NAME}) endif() -# set(TEST_NAME ${PROJECT_NAME}_tests) -# add_executable(${TEST_NAME} ${TEST_LITEHTML} ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc) -# set_target_properties(${TEST_NAME} PROPERTIES -# CXX_STANDARD 11 -# C_STANDARD 99 -# PUBLIC_HEADER "${HEADER_LITEHTML}" -# ) -# target_include_directories(${TEST_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/containers) -# target_link_libraries(${TEST_NAME} PRIVATE ${PROJECT_NAME}) -# # tests -# add_test(NAME contextTest COMMAND ${TEST_NAME} 1) -# add_test(NAME cssTest COMMAND ${TEST_NAME} 2) -# add_test(NAME documentTest COMMAND ${TEST_NAME} 3) -# add_test(NAME layoutGlobalTest COMMAND ${TEST_NAME} 4) -# add_test(NAME mediaQueryTest COMMAND ${TEST_NAME} 5) -# add_test(NAME webColorTest COMMAND ${TEST_NAME} 6) -# endif() +# set(TEST_NAME ${PROJECT_NAME}_tests) add_executable(${TEST_NAME} +# ${TEST_LITEHTML} ${CMAKE_CURRENT_SOURCE_DIR}/src/master.css.inc) +# set_target_properties(${TEST_NAME} PROPERTIES CXX_STANDARD 11 C_STANDARD 99 +# PUBLIC_HEADER "${HEADER_LITEHTML}" ) target_include_directories(${TEST_NAME} +# PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/containers) +# target_link_libraries(${TEST_NAME} PRIVATE ${PROJECT_NAME}) # tests +# add_test(NAME contextTest COMMAND ${TEST_NAME} 1) add_test(NAME cssTest +# COMMAND ${TEST_NAME} 2) add_test(NAME documentTest COMMAND ${TEST_NAME} 3) +# add_test(NAME layoutGlobalTest COMMAND ${TEST_NAME} 4) add_test(NAME +# mediaQueryTest COMMAND ${TEST_NAME} 5) add_test(NAME webColorTest COMMAND +# ${TEST_NAME} 6) endif() diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_container.cpp b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_container.cpp index 18d6b6de7..a70aabffc 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_container.cpp +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_container.cpp @@ -1,1027 +1,754 @@ #include "cairo_container.h" #define _USE_MATH_DEFINES #include -#include "cairo_font.h" #include -cairo_container::cairo_container(void) -{ - m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2); - m_temp_cr = cairo_create(m_temp_surface); - m_font_link = NULL; - CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_ALL, IID_IMLangFontLink2, (void**) &m_font_link); - InitializeCriticalSection(&m_img_sync); +#include "cairo_font.h" + +cairo_container::cairo_container(void) { + m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2); + m_temp_cr = cairo_create(m_temp_surface); + m_font_link = NULL; + CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_ALL, IID_IMLangFontLink2, (void**)&m_font_link); + InitializeCriticalSection(&m_img_sync); } -cairo_container::~cairo_container(void) -{ - clear_images(); - if(m_font_link) - { - m_font_link->Release(); - } - cairo_surface_destroy(m_temp_surface); - cairo_destroy(m_temp_cr); - DeleteCriticalSection(&m_img_sync); +cairo_container::~cairo_container(void) { + clear_images(); + if (m_font_link) { + m_font_link->Release(); + } + cairo_surface_destroy(m_temp_surface); + cairo_destroy(m_temp_cr); + DeleteCriticalSection(&m_img_sync); } -litehtml::uint_ptr cairo_container::create_font( const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm ) -{ - std::wstring fnt_name = L"sans-serif"; +litehtml::uint_ptr cairo_container::create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) { + std::wstring fnt_name = L"sans-serif"; - litehtml::string_vector fonts; - litehtml::split_string(faceName, fonts, _t(",")); - if(!fonts.empty()) - { - litehtml::trim(fonts[0]); + litehtml::string_vector fonts; + litehtml::split_string(faceName, fonts, _t(",")); + if (!fonts.empty()) { + litehtml::trim(fonts[0]); #ifdef LITEHTML_UTF8 - wchar_t* f = cairo_font::utf8_to_wchar(fonts[0].c_str()); - fnt_name = f; - delete f; + wchar_t* f = cairo_font::utf8_to_wchar(fonts[0].c_str()); + fnt_name = f; + delete f; #else - fnt_name = fonts[0]; - if (fnt_name.front() == L'"' || fnt_name.front() == L'\'') - { - fnt_name.erase(0, 1); - } - if (fnt_name.back() == L'"' || fnt_name.back() == L'\'') - { - fnt_name.erase(fnt_name.length() - 1, 1); - } + fnt_name = fonts[0]; + if (fnt_name.front() == L'"' || fnt_name.front() == L'\'') { + fnt_name.erase(0, 1); + } + if (fnt_name.back() == L'"' || fnt_name.back() == L'\'') { + fnt_name.erase(fnt_name.length() - 1, 1); + } #endif - } + } - cairo_font* fnt = new cairo_font( m_font_link, - fnt_name.c_str(), - size, - weight, - (italic == litehtml::fontStyleItalic) ? TRUE : FALSE, - (decoration & litehtml::font_decoration_linethrough) ? TRUE : FALSE, - (decoration & litehtml::font_decoration_underline) ? TRUE : FALSE); + cairo_font* fnt = new cairo_font(m_font_link, fnt_name.c_str(), size, weight, (italic == litehtml::fontStyleItalic) ? TRUE : FALSE, (decoration & litehtml::font_decoration_linethrough) ? TRUE : FALSE, (decoration & litehtml::font_decoration_underline) ? TRUE : FALSE); - cairo_save(m_temp_cr); - fnt->load_metrics(m_temp_cr); + cairo_save(m_temp_cr); + fnt->load_metrics(m_temp_cr); - if(fm) - { - fm->ascent = fnt->metrics().ascent; - fm->descent = fnt->metrics().descent; - fm->height = fnt->metrics().height; - fm->x_height = fnt->metrics().x_height; - if(italic == litehtml::fontStyleItalic || decoration) - { - fm->draw_spaces = true; - } else - { - fm->draw_spaces = false; - } - } + if (fm) { + fm->ascent = fnt->metrics().ascent; + fm->descent = fnt->metrics().descent; + fm->height = fnt->metrics().height; + fm->x_height = fnt->metrics().x_height; + if (italic == litehtml::fontStyleItalic || decoration) { + fm->draw_spaces = true; + } else { + fm->draw_spaces = false; + } + } - cairo_restore(m_temp_cr); + cairo_restore(m_temp_cr); - return (litehtml::uint_ptr) fnt; + return (litehtml::uint_ptr)fnt; } -void cairo_container::delete_font( litehtml::uint_ptr hFont ) -{ - cairo_font* fnt = (cairo_font*) hFont; - if(fnt) - { - delete fnt; - } +void cairo_container::delete_font(litehtml::uint_ptr hFont) { + cairo_font* fnt = (cairo_font*)hFont; + if (fnt) { + delete fnt; + } } -int cairo_container::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont ) -{ - cairo_font* fnt = (cairo_font*) hFont; - - cairo_save(m_temp_cr); - int ret = fnt->text_width(m_temp_cr, text); - cairo_restore(m_temp_cr); - return ret; +int cairo_container::text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) { + cairo_font* fnt = (cairo_font*)hFont; + + cairo_save(m_temp_cr); + int ret = fnt->text_width(m_temp_cr, text); + cairo_restore(m_temp_cr); + return ret; } -void cairo_container::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos ) -{ - if(hFont) - { - cairo_font* fnt = (cairo_font*) hFont; - cairo_t* cr = (cairo_t*) hdc; - cairo_save(cr); +void cairo_container::draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) { + if (hFont) { + cairo_font* fnt = (cairo_font*)hFont; + cairo_t* cr = (cairo_t*)hdc; + cairo_save(cr); - apply_clip(cr); + apply_clip(cr); - int x = pos.left(); - int y = pos.bottom() - fnt->metrics().descent; + int x = pos.left(); + int y = pos.bottom() - fnt->metrics().descent; - set_color(cr, color); - fnt->show_text(cr, x, y, text); + set_color(cr, color); + fnt->show_text(cr, x, y, text); - cairo_restore(cr); - } + cairo_restore(cr); + } } -int cairo_container::pt_to_px( int pt ) const -{ - HDC dc = GetDC(NULL); - int ret = MulDiv(pt, GetDeviceCaps(dc, LOGPIXELSY), 72); - ReleaseDC(NULL, dc); - return ret; +int cairo_container::pt_to_px(int pt) const { + HDC dc = GetDC(NULL); + int ret = MulDiv(pt, GetDeviceCaps(dc, LOGPIXELSY), 72); + ReleaseDC(NULL, dc); + return ret; } -int cairo_container::get_default_font_size() const -{ - return 16; +int cairo_container::get_default_font_size() const { return 16; } + +void cairo_container::draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) { + if (!marker.image.empty()) { + std::wstring url; + t_make_url(marker.image.c_str(), marker.baseurl, url); + + lock_images_cache(); + images_map::iterator img_i = m_images.find(url.c_str()); + if (img_i != m_images.end()) { + if (img_i->second) { + draw_txdib((cairo_t*)hdc, img_i->second.get(), marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); + } + } + unlock_images_cache(); + } else { + switch (marker.marker_type) { + case litehtml::list_style_type_circle: { + draw_ellipse((cairo_t*)hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 0.5); + } break; + case litehtml::list_style_type_disc: { + fill_ellipse((cairo_t*)hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color); + } break; + case litehtml::list_style_type_square: + if (hdc) { + cairo_t* cr = (cairo_t*)hdc; + cairo_save(cr); + + cairo_new_path(cr); + cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); + + set_color(cr, marker.color); + cairo_fill(cr); + cairo_restore(cr); + } + break; + } + } } -void cairo_container::draw_list_marker( litehtml::uint_ptr hdc, const litehtml::list_marker& marker ) -{ - if(!marker.image.empty()) - { - std::wstring url; - t_make_url(marker.image.c_str(), marker.baseurl, url); - - lock_images_cache(); - images_map::iterator img_i = m_images.find(url.c_str()); - if(img_i != m_images.end()) - { - if(img_i->second) - { - draw_txdib((cairo_t*)hdc, img_i->second.get(), marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); - } - } - unlock_images_cache(); - } else - { - switch(marker.marker_type) - { - case litehtml::list_style_type_circle: - { - draw_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 0.5); - } - break; - case litehtml::list_style_type_disc: - { - fill_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color); - } - break; - case litehtml::list_style_type_square: - if(hdc) - { - cairo_t* cr = (cairo_t*) hdc; - cairo_save(cr); - - cairo_new_path(cr); - cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); - - set_color(cr, marker.color); - cairo_fill(cr); - cairo_restore(cr); - } - break; - } - } +void cairo_container::load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) { + std::wstring url; + t_make_url(src, baseurl, url); + lock_images_cache(); + if (m_images.find(url.c_str()) == m_images.end()) { + unlock_images_cache(); + image_ptr img = get_image(url.c_str(), redraw_on_ready); + lock_images_cache(); + m_images[url] = img; + unlock_images_cache(); + } else { + unlock_images_cache(); + } } -void cairo_container::load_image( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready ) -{ - std::wstring url; - t_make_url(src, baseurl, url); - lock_images_cache(); - if(m_images.find(url.c_str()) == m_images.end()) - { - unlock_images_cache(); - image_ptr img = get_image(url.c_str(), redraw_on_ready); - lock_images_cache(); - m_images[url] = img; - unlock_images_cache(); - } else - { - unlock_images_cache(); - } +void cairo_container::get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) { + std::wstring url; + t_make_url(src, baseurl, url); + sz.width = 0; + sz.height = 0; + + lock_images_cache(); + images_map::iterator img = m_images.find(url.c_str()); + if (img != m_images.end()) { + if (img->second) { + sz.width = img->second->getWidth(); + sz.height = img->second->getHeight(); + } + } + unlock_images_cache(); } -void cairo_container::get_image_size( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz ) -{ - std::wstring url; - t_make_url(src, baseurl, url); +void cairo_container::draw_image(litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos) { + cairo_t* cr = (cairo_t*)hdc; + cairo_save(cr); + apply_clip(cr); - sz.width = 0; - sz.height = 0; - - lock_images_cache(); - images_map::iterator img = m_images.find(url.c_str()); - if(img != m_images.end()) - { - if(img->second) - { - sz.width = img->second->getWidth(); - sz.height = img->second->getHeight(); - } - } - unlock_images_cache(); + std::wstring url; + t_make_url(src, baseurl, url); + lock_images_cache(); + images_map::iterator img = m_images.find(url.c_str()); + if (img != m_images.end()) { + if (img->second) { + draw_txdib(cr, img->second.get(), pos.x, pos.y, pos.width, pos.height); + } + } + unlock_images_cache(); + cairo_restore(cr); } -void cairo_container::draw_image( litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos ) -{ - cairo_t* cr = (cairo_t*) hdc; - cairo_save(cr); - apply_clip(cr); +void cairo_container::draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) { + cairo_t* cr = (cairo_t*)hdc; + cairo_save(cr); + apply_clip(cr); - std::wstring url; - t_make_url(src, baseurl, url); - lock_images_cache(); - images_map::iterator img = m_images.find(url.c_str()); - if(img != m_images.end()) - { - if(img->second) - { - draw_txdib(cr, img->second.get(), pos.x, pos.y, pos.width, pos.height); - } - } - unlock_images_cache(); - cairo_restore(cr); + rounded_rectangle(cr, bg.border_box, bg.border_radius); + cairo_clip(cr); + + cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height); + cairo_clip(cr); + + if (bg.color.alpha) { + set_color(cr, bg.color); + cairo_paint(cr); + } + + std::wstring url; + t_make_url(bg.image.c_str(), bg.baseurl.c_str(), url); + + lock_images_cache(); + images_map::iterator img_i = m_images.find(url.c_str()); + if (img_i != m_images.end() && img_i->second) { + image_ptr bgbmp = img_i->second; + + image_ptr new_img; + if (bg.image_size.width != bgbmp->getWidth() || bg.image_size.height != bgbmp->getHeight()) { + new_img = image_ptr(new CTxDIB); + bgbmp->resample(bg.image_size.width, bg.image_size.height, new_img.get()); + bgbmp = new_img; + } + + cairo_surface_t* img = cairo_image_surface_create_for_data((unsigned char*)bgbmp->getBits(), CAIRO_FORMAT_ARGB32, bgbmp->getWidth(), bgbmp->getHeight(), bgbmp->getWidth() * 4); + cairo_pattern_t* pattern = cairo_pattern_create_for_surface(img); + cairo_matrix_t flib_m; + cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); + cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y); + cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); + cairo_pattern_set_matrix(pattern, &flib_m); + + switch (bg.repeat) { + case litehtml::background_repeat_no_repeat: + draw_txdib(cr, bgbmp.get(), bg.position_x, bg.position_y, bgbmp->getWidth(), bgbmp->getHeight()); + break; + + case litehtml::background_repeat_repeat_x: + cairo_set_source(cr, pattern); + cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->getHeight()); + cairo_fill(cr); + break; + + case litehtml::background_repeat_repeat_y: + cairo_set_source(cr, pattern); + cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->getWidth(), bg.clip_box.height); + cairo_fill(cr); + break; + + case litehtml::background_repeat_repeat: + cairo_set_source(cr, pattern); + cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height); + cairo_fill(cr); + break; + } + + cairo_pattern_destroy(pattern); + cairo_surface_destroy(img); + } + unlock_images_cache(); + cairo_restore(cr); } -void cairo_container::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg ) -{ - cairo_t* cr = (cairo_t*) hdc; - cairo_save(cr); - apply_clip(cr); +bool cairo_container::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg) { + if (rx > 0 && ry > 0) { + cairo_save(cr); - rounded_rectangle(cr, bg.border_box, bg.border_radius); - cairo_clip(cr); + cairo_translate(cr, x, y); + cairo_scale(cr, 1, ry / rx); + cairo_translate(cr, -x, -y); - cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height); - cairo_clip(cr); + if (neg) { + cairo_arc_negative(cr, x, y, rx, a1, a2); + } else { + cairo_arc(cr, x, y, rx, a1, a2); + } - if(bg.color.alpha) - { - set_color(cr, bg.color); - cairo_paint(cr); - } - - std::wstring url; - t_make_url(bg.image.c_str(), bg.baseurl.c_str(), url); - - lock_images_cache(); - images_map::iterator img_i = m_images.find(url.c_str()); - if(img_i != m_images.end() && img_i->second) - { - image_ptr bgbmp = img_i->second; - - image_ptr new_img; - if(bg.image_size.width != bgbmp->getWidth() || bg.image_size.height != bgbmp->getHeight()) - { - new_img = image_ptr(new CTxDIB); - bgbmp->resample(bg.image_size.width, bg.image_size.height, new_img.get()); - bgbmp = new_img; - } - - - cairo_surface_t* img = cairo_image_surface_create_for_data((unsigned char*) bgbmp->getBits(), CAIRO_FORMAT_ARGB32, bgbmp->getWidth(), bgbmp->getHeight(), bgbmp->getWidth() * 4); - cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img); - cairo_matrix_t flib_m; - cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); - cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y); - cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); - cairo_pattern_set_matrix (pattern, &flib_m); - - switch(bg.repeat) - { - case litehtml::background_repeat_no_repeat: - draw_txdib(cr, bgbmp.get(), bg.position_x, bg.position_y, bgbmp->getWidth(), bgbmp->getHeight()); - break; - - case litehtml::background_repeat_repeat_x: - cairo_set_source(cr, pattern); - cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->getHeight()); - cairo_fill(cr); - break; - - case litehtml::background_repeat_repeat_y: - cairo_set_source(cr, pattern); - cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->getWidth(), bg.clip_box.height); - cairo_fill(cr); - break; - - case litehtml::background_repeat_repeat: - cairo_set_source(cr, pattern); - cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height); - cairo_fill(cr); - break; - } - - cairo_pattern_destroy(pattern); - cairo_surface_destroy(img); - } - unlock_images_cache(); - cairo_restore(cr); + cairo_restore(cr); + return true; + } + return false; } -bool cairo_container::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg) -{ - if(rx > 0 && ry > 0) - { - cairo_save(cr); +void cairo_container::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) { + cairo_t* cr = (cairo_t*)hdc; + cairo_save(cr); + apply_clip(cr); - cairo_translate(cr, x, y); - cairo_scale(cr, 1, ry / rx); - cairo_translate(cr, -x, -y); + cairo_new_path(cr); - if(neg) - { - cairo_arc_negative(cr, x, y, rx, a1, a2); - } else - { - cairo_arc(cr, x, y, rx, a1, a2); - } + int bdr_top = 0; + int bdr_bottom = 0; + int bdr_left = 0; + int bdr_right = 0; - cairo_restore(cr); - return true; - } - return false; + if (borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) { + bdr_top = (int)borders.top.width; + } + if (borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) { + bdr_bottom = (int)borders.bottom.width; + } + if (borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) { + bdr_left = (int)borders.left.width; + } + if (borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) { + bdr_right = (int)borders.right.width; + } + + // draw right border + if (bdr_right) { + set_color(cr, borders.right.color); + + double r_top = (double)borders.radius.top_right_x; + double r_bottom = (double)borders.radius.bottom_right_x; + + if (r_top) { + double end_angle = 2.0 * M_PI; + double start_angle = end_angle - M_PI / 2.0 / ((double)bdr_top / (double)bdr_right + 0.5); + + if (!add_path_arc(cr, draw_pos.right() - r_top, draw_pos.top() + r_top, r_top - bdr_right, r_top - bdr_right + (bdr_right - bdr_top), end_angle, start_angle, true)) { + cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); + } + + if (!add_path_arc(cr, draw_pos.right() - r_top, draw_pos.top() + r_top, r_top, r_top, start_angle, end_angle, false)) { + cairo_line_to(cr, draw_pos.right(), draw_pos.top()); + } + } else { + cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); + cairo_line_to(cr, draw_pos.right(), draw_pos.top()); + } + + if (r_bottom) { + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom); + + double start_angle = 0; + double end_angle = start_angle + M_PI / 2.0 / ((double)bdr_bottom / (double)bdr_right + 0.5); + + if (!add_path_arc(cr, draw_pos.right() - r_bottom, draw_pos.bottom() - r_bottom, r_bottom, r_bottom, start_angle, end_angle, false)) { + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); + } + + if (!add_path_arc(cr, draw_pos.right() - r_bottom, draw_pos.bottom() - r_bottom, r_bottom - bdr_right, r_bottom - bdr_right + (bdr_right - bdr_bottom), end_angle, start_angle, true)) { + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); + } + } else { + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); + } + + cairo_fill(cr); + } + + // draw bottom border + if (bdr_bottom) { + set_color(cr, borders.bottom.color); + + double r_left = borders.radius.bottom_left_x; + double r_right = borders.radius.bottom_right_x; + + if (r_left) { + double start_angle = M_PI / 2.0; + double end_angle = start_angle + M_PI / 2.0 / ((double)bdr_left / (double)bdr_bottom + 0.5); + + if (!add_path_arc(cr, draw_pos.left() + r_left, draw_pos.bottom() - r_left, r_left - bdr_bottom + (bdr_bottom - bdr_left), r_left - bdr_bottom, start_angle, end_angle, false)) { + cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); + } + + if (!add_path_arc(cr, draw_pos.left() + r_left, draw_pos.bottom() - r_left, r_left, r_left, end_angle, start_angle, true)) { + cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); + } + } else { + cairo_move_to(cr, draw_pos.left(), draw_pos.bottom()); + cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); + } + + if (r_right) { + cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom()); + + double end_angle = M_PI / 2.0; + double start_angle = end_angle - M_PI / 2.0 / ((double)bdr_right / (double)bdr_bottom + 0.5); + + if (!add_path_arc(cr, draw_pos.right() - r_right, draw_pos.bottom() - r_right, r_right, r_right, end_angle, start_angle, true)) { + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); + } + + if (!add_path_arc(cr, draw_pos.right() - r_right, draw_pos.bottom() - r_right, r_right - bdr_bottom + (bdr_bottom - bdr_right), r_right - bdr_bottom, start_angle, end_angle, false)) { + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); + } + } else { + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); + } + + cairo_fill(cr); + } + + // draw top border + if (bdr_top) { + set_color(cr, borders.top.color); + + double r_left = borders.radius.top_left_x; + double r_right = borders.radius.top_right_x; + + if (r_left) { + double end_angle = M_PI * 3.0 / 2.0; + double start_angle = end_angle - M_PI / 2.0 / ((double)bdr_left / (double)bdr_top + 0.5); + + if (!add_path_arc(cr, draw_pos.left() + r_left, draw_pos.top() + r_left, r_left, r_left, end_angle, start_angle, true)) { + cairo_move_to(cr, draw_pos.left(), draw_pos.top()); + } + + if (!add_path_arc(cr, draw_pos.left() + r_left, draw_pos.top() + r_left, r_left - bdr_top + (bdr_top - bdr_left), r_left - bdr_top, start_angle, end_angle, false)) { + cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); + } + } else { + cairo_move_to(cr, draw_pos.left(), draw_pos.top()); + cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); + } + + if (r_right) { + cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top); + + double start_angle = M_PI * 3.0 / 2.0; + double end_angle = start_angle + M_PI / 2.0 / ((double)bdr_right / (double)bdr_top + 0.5); + + if (!add_path_arc(cr, draw_pos.right() - r_right, draw_pos.top() + r_right, r_right - bdr_top + (bdr_top - bdr_right), r_right - bdr_top, start_angle, end_angle, false)) { + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); + } + + if (!add_path_arc(cr, draw_pos.right() - r_right, draw_pos.top() + r_right, r_right, r_right, end_angle, start_angle, true)) { + cairo_line_to(cr, draw_pos.right(), draw_pos.top()); + } + } else { + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); + cairo_line_to(cr, draw_pos.right(), draw_pos.top()); + } + + cairo_fill(cr); + } + + // draw left border + if (bdr_left) { + set_color(cr, borders.left.color); + + double r_top = borders.radius.top_left_x; + double r_bottom = borders.radius.bottom_left_x; + + if (r_top) { + double start_angle = M_PI; + double end_angle = start_angle + M_PI / 2.0 / ((double)bdr_top / (double)bdr_left + 0.5); + + if (!add_path_arc(cr, draw_pos.left() + r_top, draw_pos.top() + r_top, r_top - bdr_left, r_top - bdr_left + (bdr_left - bdr_top), start_angle, end_angle, false)) { + cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); + } + + if (!add_path_arc(cr, draw_pos.left() + r_top, draw_pos.top() + r_top, r_top, r_top, end_angle, start_angle, true)) { + cairo_line_to(cr, draw_pos.left(), draw_pos.top()); + } + } else { + cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); + cairo_line_to(cr, draw_pos.left(), draw_pos.top()); + } + + if (r_bottom) { + cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom); + + double end_angle = M_PI; + double start_angle = end_angle - M_PI / 2.0 / ((double)bdr_bottom / (double)bdr_left + 0.5); + + if (!add_path_arc(cr, draw_pos.left() + r_bottom, draw_pos.bottom() - r_bottom, r_bottom, r_bottom, end_angle, start_angle, true)) { + cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); + } + + if (!add_path_arc(cr, draw_pos.left() + r_bottom, draw_pos.bottom() - r_bottom, r_bottom - bdr_left, r_bottom - bdr_left + (bdr_left - bdr_bottom), start_angle, end_angle, false)) { + cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); + } + } else { + cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); + cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); + } + + cairo_fill(cr); + } + cairo_restore(cr); } -void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root ) -{ - cairo_t* cr = (cairo_t*) hdc; - cairo_save(cr); - apply_clip(cr); - - cairo_new_path(cr); - - int bdr_top = 0; - int bdr_bottom = 0; - int bdr_left = 0; - int bdr_right = 0; - - if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) - { - bdr_top = (int) borders.top.width; - } - if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) - { - bdr_bottom = (int) borders.bottom.width; - } - if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) - { - bdr_left = (int) borders.left.width; - } - if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) - { - bdr_right = (int) borders.right.width; - } - - // draw right border - if (bdr_right) - { - set_color(cr, borders.right.color); - - double r_top = (double) borders.radius.top_right_x; - double r_bottom = (double) borders.radius.bottom_right_x; - - if(r_top) - { - double end_angle = 2.0 * M_PI; - double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_top / (double) bdr_right + 0.5); - - if (!add_path_arc(cr, - draw_pos.right() - r_top, - draw_pos.top() + r_top, - r_top - bdr_right, - r_top - bdr_right + (bdr_right - bdr_top), - end_angle, - start_angle, true)) - { - cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); - } - - if (!add_path_arc(cr, - draw_pos.right() - r_top, - draw_pos.top() + r_top, - r_top, - r_top, - start_angle, - end_angle, false)) - { - cairo_line_to(cr, draw_pos.right(), draw_pos.top()); - } - } else - { - cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); - cairo_line_to(cr, draw_pos.right(), draw_pos.top()); - } - - if(r_bottom) - { - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom); - - double start_angle = 0; - double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_right + 0.5); - - if (!add_path_arc(cr, - draw_pos.right() - r_bottom, - draw_pos.bottom() - r_bottom, - r_bottom, - r_bottom, - start_angle, - end_angle, false)) - { - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); - } - - if (!add_path_arc(cr, - draw_pos.right() - r_bottom, - draw_pos.bottom() - r_bottom, - r_bottom - bdr_right, - r_bottom - bdr_right + (bdr_right - bdr_bottom), - end_angle, - start_angle, true)) - { - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); - } - } else - { - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); - } - - cairo_fill(cr); - } - - // draw bottom border - if(bdr_bottom) - { - set_color(cr, borders.bottom.color); - - double r_left = borders.radius.bottom_left_x; - double r_right = borders.radius.bottom_right_x; - - if(r_left) - { - double start_angle = M_PI / 2.0; - double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_left / (double) bdr_bottom + 0.5); - - if (!add_path_arc(cr, - draw_pos.left() + r_left, - draw_pos.bottom() - r_left, - r_left - bdr_bottom + (bdr_bottom - bdr_left), - r_left - bdr_bottom, - start_angle, - end_angle, false)) - { - cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); - } - - if (!add_path_arc(cr, - draw_pos.left() + r_left, - draw_pos.bottom() - r_left, - r_left, - r_left, - end_angle, - start_angle, true)) - { - cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); - } - } else - { - cairo_move_to(cr, draw_pos.left(), draw_pos.bottom()); - cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); - } - - if(r_right) - { - cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom()); - - double end_angle = M_PI / 2.0; - double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_right / (double) bdr_bottom + 0.5); - - if (!add_path_arc(cr, - draw_pos.right() - r_right, - draw_pos.bottom() - r_right, - r_right, - r_right, - end_angle, - start_angle, true)) - { - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); - } - - if (!add_path_arc(cr, - draw_pos.right() - r_right, - draw_pos.bottom() - r_right, - r_right - bdr_bottom + (bdr_bottom - bdr_right), - r_right - bdr_bottom, - start_angle, - end_angle, false)) - { - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); - } - } else - { - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); - } - - cairo_fill(cr); - } - - // draw top border - if(bdr_top) - { - set_color(cr, borders.top.color); - - double r_left = borders.radius.top_left_x; - double r_right = borders.radius.top_right_x; - - if(r_left) - { - double end_angle = M_PI * 3.0 / 2.0; - double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_left / (double) bdr_top + 0.5); - - if (!add_path_arc(cr, - draw_pos.left() + r_left, - draw_pos.top() + r_left, - r_left, - r_left, - end_angle, - start_angle, true)) - { - cairo_move_to(cr, draw_pos.left(), draw_pos.top()); - } - - if (!add_path_arc(cr, - draw_pos.left() + r_left, - draw_pos.top() + r_left, - r_left - bdr_top + (bdr_top - bdr_left), - r_left - bdr_top, - start_angle, - end_angle, false)) - { - cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); - } - } else - { - cairo_move_to(cr, draw_pos.left(), draw_pos.top()); - cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); - } - - if(r_right) - { - cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top); - - double start_angle = M_PI * 3.0 / 2.0; - double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_right / (double) bdr_top + 0.5); - - if (!add_path_arc(cr, - draw_pos.right() - r_right, - draw_pos.top() + r_right, - r_right - bdr_top + (bdr_top - bdr_right), - r_right - bdr_top, - start_angle, - end_angle, false)) - { - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); - } - - if (!add_path_arc(cr, - draw_pos.right() - r_right, - draw_pos.top() + r_right, - r_right, - r_right, - end_angle, - start_angle, true)) - { - cairo_line_to(cr, draw_pos.right(), draw_pos.top()); - } - } else - { - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); - cairo_line_to(cr, draw_pos.right(), draw_pos.top()); - } - - cairo_fill(cr); - } - - // draw left border - if (bdr_left) - { - set_color(cr, borders.left.color); - - double r_top = borders.radius.top_left_x; - double r_bottom = borders.radius.bottom_left_x; - - if(r_top) - { - double start_angle = M_PI; - double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_top / (double) bdr_left + 0.5); - - if (!add_path_arc(cr, - draw_pos.left() + r_top, - draw_pos.top() + r_top, - r_top - bdr_left, - r_top - bdr_left + (bdr_left - bdr_top), - start_angle, - end_angle, false)) - { - cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); - } - - if (!add_path_arc(cr, - draw_pos.left() + r_top, - draw_pos.top() + r_top, - r_top, - r_top, - end_angle, - start_angle, true)) - { - cairo_line_to(cr, draw_pos.left(), draw_pos.top()); - } - } else - { - cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); - cairo_line_to(cr, draw_pos.left(), draw_pos.top()); - } - - if(r_bottom) - { - cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom); - - double end_angle = M_PI; - double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_left + 0.5); - - if (!add_path_arc(cr, - draw_pos.left() + r_bottom, - draw_pos.bottom() - r_bottom, - r_bottom, - r_bottom, - end_angle, - start_angle, true)) - { - cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); - } - - if (!add_path_arc(cr, - draw_pos.left() + r_bottom, - draw_pos.bottom() - r_bottom, - r_bottom - bdr_left, - r_bottom - bdr_left + (bdr_left - bdr_bottom), - start_angle, - end_angle, false)) - { - cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); - } - } else - { - cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); - cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); - } - - cairo_fill(cr); - } - cairo_restore(cr); +void cairo_container::set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) { + litehtml::position clip_pos = pos; + litehtml::position client_pos; + get_client_rect(client_pos); + if (!valid_x) { + clip_pos.x = client_pos.x; + clip_pos.width = client_pos.width; + } + if (!valid_y) { + clip_pos.y = client_pos.y; + clip_pos.height = client_pos.height; + } + m_clips.emplace_back(clip_pos, bdr_radius); } -void cairo_container::set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) -{ - litehtml::position clip_pos = pos; - litehtml::position client_pos; - get_client_rect(client_pos); - if(!valid_x) - { - clip_pos.x = client_pos.x; - clip_pos.width = client_pos.width; - } - if(!valid_y) - { - clip_pos.y = client_pos.y; - clip_pos.height = client_pos.height; - } - m_clips.emplace_back(clip_pos, bdr_radius); +void cairo_container::del_clip() { + if (!m_clips.empty()) { + m_clips.pop_back(); + } } -void cairo_container::del_clip() -{ - if(!m_clips.empty()) - { - m_clips.pop_back(); - } +void cairo_container::apply_clip(cairo_t* cr) { + for (const auto& clip_box : m_clips) { + rounded_rectangle(cr, clip_box.box, clip_box.radius); + cairo_clip(cr); + } } -void cairo_container::apply_clip( cairo_t* cr ) -{ - for(const auto& clip_box : m_clips) - { - rounded_rectangle(cr, clip_box.box, clip_box.radius); - cairo_clip(cr); - } +void cairo_container::draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, double line_width) { + if (!cr) return; + cairo_save(cr); + + apply_clip(cr); + + cairo_new_path(cr); + + cairo_translate(cr, x + width / 2.0, y + height / 2.0); + cairo_scale(cr, width / 2.0, height / 2.0); + cairo_arc(cr, 0, 0, 1, 0, 2 * M_PI); + + set_color(cr, color); + cairo_set_line_width(cr, line_width); + cairo_stroke(cr); + + cairo_restore(cr); } -void cairo_container::draw_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, double line_width ) -{ - if(!cr) return; - cairo_save(cr); +void cairo_container::fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color) { + if (!cr) return; + cairo_save(cr); - apply_clip(cr); + apply_clip(cr); - cairo_new_path(cr); + cairo_new_path(cr); - cairo_translate (cr, x + width / 2.0, y + height / 2.0); - cairo_scale (cr, width / 2.0, height / 2.0); - cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); + cairo_translate(cr, x + width / 2.0, y + height / 2.0); + cairo_scale(cr, width / 2.0, height / 2.0); + cairo_arc(cr, 0, 0, 1, 0, 2 * M_PI); - set_color(cr, color); - cairo_set_line_width(cr, line_width); - cairo_stroke(cr); + set_color(cr, color); + cairo_fill(cr); - cairo_restore(cr); + cairo_restore(cr); } -void cairo_container::fill_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color ) -{ - if(!cr) return; - cairo_save(cr); - - apply_clip(cr); - - cairo_new_path(cr); - - cairo_translate (cr, x + width / 2.0, y + height / 2.0); - cairo_scale (cr, width / 2.0, height / 2.0); - cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); - - set_color(cr, color); - cairo_fill(cr); - - cairo_restore(cr); +void cairo_container::clear_images() { + lock_images_cache(); + m_images.clear(); + unlock_images_cache(); } -void cairo_container::clear_images() -{ - lock_images_cache(); - m_images.clear(); - unlock_images_cache(); +const litehtml::tchar_t* cairo_container::get_default_font_name() const { return _t("Times New Roman"); } + +void cairo_container::draw_txdib(cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy) { + cairo_save(cr); + + cairo_matrix_t flib_m; + cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); + + cairo_surface_t* img = NULL; + + CTxDIB rbmp; + + if (cx != bmp->getWidth() || cy != bmp->getHeight()) { + bmp->resample(cx, cy, &rbmp); + img = cairo_image_surface_create_for_data((unsigned char*)rbmp.getBits(), CAIRO_FORMAT_ARGB32, rbmp.getWidth(), rbmp.getHeight(), rbmp.getWidth() * 4); + cairo_matrix_translate(&flib_m, 0, -rbmp.getHeight()); + cairo_matrix_translate(&flib_m, x, -y); + } else { + img = cairo_image_surface_create_for_data((unsigned char*)bmp->getBits(), CAIRO_FORMAT_ARGB32, bmp->getWidth(), bmp->getHeight(), bmp->getWidth() * 4); + cairo_matrix_translate(&flib_m, 0, -bmp->getHeight()); + cairo_matrix_translate(&flib_m, x, -y); + } + + cairo_transform(cr, &flib_m); + cairo_set_source_surface(cr, img, 0, 0); + cairo_paint(cr); + + cairo_restore(cr); + cairo_surface_destroy(img); } -const litehtml::tchar_t* cairo_container::get_default_font_name() const -{ - return _t("Times New Roman"); +void cairo_container::rounded_rectangle(cairo_t* cr, const litehtml::position& pos, const litehtml::border_radiuses& radius) { + cairo_new_path(cr); + if (radius.top_left_x) { + cairo_arc(cr, pos.left() + radius.top_left_x, pos.top() + radius.top_left_x, radius.top_left_x, M_PI, M_PI * 3.0 / 2.0); + } else { + cairo_move_to(cr, pos.left(), pos.top()); + } + + cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top()); + + if (radius.top_right_x) { + cairo_arc(cr, pos.right() - radius.top_right_x, pos.top() + radius.top_right_x, radius.top_right_x, M_PI * 3.0 / 2.0, 2.0 * M_PI); + } + + cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x); + + if (radius.bottom_right_x) { + cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0); + } + + cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom()); + + if (radius.bottom_left_x) { + cairo_arc(cr, pos.left() + radius.bottom_left_x, pos.bottom() - radius.bottom_left_x, radius.bottom_left_x, M_PI / 2.0, M_PI); + } } -void cairo_container::draw_txdib( cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy ) -{ - cairo_save(cr); - - cairo_matrix_t flib_m; - cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); - - cairo_surface_t* img = NULL; - - CTxDIB rbmp; - - if(cx != bmp->getWidth() || cy != bmp->getHeight()) - { - bmp->resample(cx, cy, &rbmp); - img = cairo_image_surface_create_for_data((unsigned char*) rbmp.getBits(), CAIRO_FORMAT_ARGB32, rbmp.getWidth(), rbmp.getHeight(), rbmp.getWidth() * 4); - cairo_matrix_translate(&flib_m, 0, -rbmp.getHeight()); - cairo_matrix_translate(&flib_m, x, -y); - } else - { - img = cairo_image_surface_create_for_data((unsigned char*) bmp->getBits(), CAIRO_FORMAT_ARGB32, bmp->getWidth(), bmp->getHeight(), bmp->getWidth() * 4); - cairo_matrix_translate(&flib_m, 0, -bmp->getHeight()); - cairo_matrix_translate(&flib_m, x, -y); - } - - cairo_transform(cr, &flib_m); - cairo_set_source_surface(cr, img, 0, 0); - cairo_paint(cr); - - cairo_restore(cr); - cairo_surface_destroy(img); +void cairo_container::remove_image(std::wstring& url) { + lock_images_cache(); + images_map::iterator i = m_images.find(url); + if (i != m_images.end()) { + m_images.erase(i); + } + unlock_images_cache(); } -void cairo_container::rounded_rectangle(cairo_t* cr, const litehtml::position& pos, const litehtml::border_radiuses& radius) -{ - cairo_new_path(cr); - if(radius.top_left_x) - { - cairo_arc(cr, pos.left() + radius.top_left_x, pos.top() + radius.top_left_x, radius.top_left_x, M_PI, M_PI * 3.0 / 2.0); - } else - { - cairo_move_to(cr, pos.left(), pos.top()); - } - - cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top()); - - if(radius.top_right_x) - { - cairo_arc(cr, pos.right() - radius.top_right_x, pos.top() + radius.top_right_x, radius.top_right_x, M_PI * 3.0 / 2.0, 2.0 * M_PI); - } - - cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x); - - if(radius.bottom_right_x) - { - cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0); - } - - cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom()); - - if(radius.bottom_left_x) - { - cairo_arc(cr, pos.left() + radius.bottom_left_x, pos.bottom() - radius.bottom_left_x, radius.bottom_left_x, M_PI / 2.0, M_PI); - } +void cairo_container::add_image(std::wstring& url, image_ptr& img) { + lock_images_cache(); + images_map::iterator i = m_images.find(url); + if (i != m_images.end()) { + if (img) { + i->second = img; + } else { + m_images.erase(i); + } + } + unlock_images_cache(); } -void cairo_container::remove_image( std::wstring& url ) -{ - lock_images_cache(); - images_map::iterator i = m_images.find(url); - if(i != m_images.end()) - { - m_images.erase(i); - } - unlock_images_cache(); +void cairo_container::lock_images_cache() { EnterCriticalSection(&m_img_sync); } + +void cairo_container::unlock_images_cache() { LeaveCriticalSection(&m_img_sync); } + +std::shared_ptr cairo_container::create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) { return 0; } + +void cairo_container::get_media_features(litehtml::media_features& media) const { + litehtml::position client; + get_client_rect(client); + HDC hdc = GetDC(NULL); + + media.type = litehtml::media_type_screen; + media.width = client.width; + media.height = client.height; + media.color = 8; + media.monochrome = 0; + media.color_index = 256; + media.resolution = GetDeviceCaps(hdc, LOGPIXELSX); + media.device_width = GetDeviceCaps(hdc, HORZRES); + media.device_height = GetDeviceCaps(hdc, VERTRES); + + ReleaseDC(NULL, hdc); } -void cairo_container::add_image(std::wstring& url, image_ptr& img) -{ - lock_images_cache(); - images_map::iterator i = m_images.find(url); - if(i != m_images.end()) - { - if(img) - { - i->second = img; - } else - { - m_images.erase(i); - } - } - unlock_images_cache(); +void cairo_container::get_language(litehtml::tstring& language, litehtml::tstring& culture) const { + language = _t("en"); + culture = _t(""); } -void cairo_container::lock_images_cache() -{ - EnterCriticalSection(&m_img_sync); +void cairo_container::make_url_utf8(const char* url, const char* basepath, std::wstring& out) { + wchar_t* urlW = cairo_font::utf8_to_wchar(url); + wchar_t* basepathW = cairo_font::utf8_to_wchar(basepath); + make_url(urlW, basepathW, out); + + if (urlW) delete urlW; + if (basepathW) delete basepathW; } -void cairo_container::unlock_images_cache() -{ - LeaveCriticalSection(&m_img_sync); -} - -std::shared_ptr cairo_container::create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) -{ - return 0; -} - -void cairo_container::get_media_features(litehtml::media_features& media) const -{ - litehtml::position client; - get_client_rect(client); - HDC hdc = GetDC(NULL); - - media.type = litehtml::media_type_screen; - media.width = client.width; - media.height = client.height; - media.color = 8; - media.monochrome = 0; - media.color_index = 256; - media.resolution = GetDeviceCaps(hdc, LOGPIXELSX); - media.device_width = GetDeviceCaps(hdc, HORZRES); - media.device_height = GetDeviceCaps(hdc, VERTRES); - - ReleaseDC(NULL, hdc); -} - -void cairo_container::get_language(litehtml::tstring& language, litehtml::tstring & culture) const -{ - language = _t("en"); - culture = _t(""); -} - -void cairo_container::make_url_utf8( const char* url, const char* basepath, std::wstring& out ) -{ - wchar_t* urlW = cairo_font::utf8_to_wchar(url); - wchar_t* basepathW = cairo_font::utf8_to_wchar(basepath); - make_url(urlW, basepathW, out); - - if(urlW) delete urlW; - if(basepathW) delete basepathW; -} - -void cairo_container::transform_text( litehtml::tstring& text, litehtml::text_transform tt ) -{ - if(text.empty()) return; +void cairo_container::transform_text(litehtml::tstring& text, litehtml::text_transform tt) { + if (text.empty()) return; #ifndef LITEHTML_UTF8 - switch(tt) - { - case litehtml::text_transform_capitalize: - if(!text.empty()) - { - text[0] = (WCHAR) CharUpper((LPWSTR) text[0]); - } - break; - case litehtml::text_transform_uppercase: - for(size_t i = 0; i < text.length(); i++) - { - text[i] = (WCHAR) CharUpper((LPWSTR) text[i]); - } - break; - case litehtml::text_transform_lowercase: - for(size_t i = 0; i < text.length(); i++) - { - text[i] = (WCHAR) CharLower((LPWSTR) text[i]); - } - break; - } + switch (tt) { + case litehtml::text_transform_capitalize: + if (!text.empty()) { + text[0] = (WCHAR)CharUpper((LPWSTR)text[0]); + } + break; + case litehtml::text_transform_uppercase: + for (size_t i = 0; i < text.length(); i++) { + text[i] = (WCHAR)CharUpper((LPWSTR)text[i]); + } + break; + case litehtml::text_transform_lowercase: + for (size_t i = 0; i < text.length(); i++) { + text[i] = (WCHAR)CharLower((LPWSTR)text[i]); + } + break; + } #else - LPWSTR txt = cairo_font::utf8_to_wchar(text.c_str()); - switch(tt) - { - case litehtml::text_transform_capitalize: - CharUpperBuff(txt, 1); - break; - case litehtml::text_transform_uppercase: - CharUpperBuff(txt, lstrlen(txt)); - break; - case litehtml::text_transform_lowercase: - CharLowerBuff(txt, lstrlen(txt)); - break; - } - LPSTR txtA = cairo_font::wchar_to_utf8(txt); - text = txtA; - delete txtA; - delete txt; + LPWSTR txt = cairo_font::utf8_to_wchar(text.c_str()); + switch (tt) { + case litehtml::text_transform_capitalize: + CharUpperBuff(txt, 1); + break; + case litehtml::text_transform_uppercase: + CharUpperBuff(txt, lstrlen(txt)); + break; + case litehtml::text_transform_lowercase: + CharLowerBuff(txt, lstrlen(txt)); + break; + } + LPSTR txtA = cairo_font::wchar_to_utf8(txt); + text = txtA; + delete txtA; + delete txt; #endif } -void cairo_container::link(const std::shared_ptr& doc, const litehtml::element::ptr& el) -{ -} +void cairo_container::link(const std::shared_ptr& doc, const litehtml::element::ptr& el) {} -litehtml::tstring cairo_container::resolve_color(const litehtml::tstring& color) const -{ - struct custom_color - { - litehtml::tchar_t* name; - int color_index; - }; +litehtml::tstring cairo_container::resolve_color(const litehtml::tstring& color) const { + struct custom_color { + litehtml::tchar_t* name; + int color_index; + }; - static custom_color colors[] = { - { _t("ActiveBorder"), COLOR_ACTIVEBORDER}, - { _t("ActiveCaption"), COLOR_ACTIVECAPTION}, - { _t("AppWorkspace"), COLOR_APPWORKSPACE }, - { _t("Background"), COLOR_BACKGROUND }, - { _t("ButtonFace"), COLOR_BTNFACE }, - { _t("ButtonHighlight"), COLOR_BTNHIGHLIGHT }, - { _t("ButtonShadow"), COLOR_BTNSHADOW }, - { _t("ButtonText"), COLOR_BTNTEXT }, - { _t("CaptionText"), COLOR_CAPTIONTEXT }, - { _t("GrayText"), COLOR_GRAYTEXT }, - { _t("Highlight"), COLOR_HIGHLIGHT }, - { _t("HighlightText"), COLOR_HIGHLIGHTTEXT }, - { _t("InactiveBorder"), COLOR_INACTIVEBORDER }, - { _t("InactiveCaption"), COLOR_INACTIVECAPTION }, - { _t("InactiveCaptionText"), COLOR_INACTIVECAPTIONTEXT }, - { _t("InfoBackground"), COLOR_INFOBK }, - { _t("InfoText"), COLOR_INFOTEXT }, - { _t("Menu"), COLOR_MENU }, - { _t("MenuText"), COLOR_MENUTEXT }, - { _t("Scrollbar"), COLOR_SCROLLBAR }, - { _t("ThreeDDarkShadow"), COLOR_3DDKSHADOW }, - { _t("ThreeDFace"), COLOR_3DFACE }, - { _t("ThreeDHighlight"), COLOR_3DHILIGHT }, - { _t("ThreeDLightShadow"), COLOR_3DLIGHT }, - { _t("ThreeDShadow"), COLOR_3DSHADOW }, - { _t("Window"), COLOR_WINDOW }, - { _t("WindowFrame"), COLOR_WINDOWFRAME }, - { _t("WindowText"), COLOR_WINDOWTEXT } - }; + static custom_color colors[] = {{_t("ActiveBorder"), COLOR_ACTIVEBORDER}, {_t("ActiveCaption"), COLOR_ACTIVECAPTION}, {_t("AppWorkspace"), COLOR_APPWORKSPACE}, {_t("Background"), COLOR_BACKGROUND}, {_t("ButtonFace"), COLOR_BTNFACE}, {_t("ButtonHighlight"), COLOR_BTNHIGHLIGHT}, {_t("ButtonShadow"), COLOR_BTNSHADOW}, {_t("ButtonText"), COLOR_BTNTEXT}, {_t("CaptionText"), COLOR_CAPTIONTEXT}, {_t("GrayText"), COLOR_GRAYTEXT}, {_t("Highlight"), COLOR_HIGHLIGHT}, {_t("HighlightText"), COLOR_HIGHLIGHTTEXT}, {_t("InactiveBorder"), COLOR_INACTIVEBORDER}, {_t("InactiveCaption"), COLOR_INACTIVECAPTION}, {_t("InactiveCaptionText"), COLOR_INACTIVECAPTIONTEXT}, {_t("InfoBackground"), COLOR_INFOBK}, {_t("InfoText"), COLOR_INFOTEXT}, {_t("Menu"), COLOR_MENU}, + {_t("MenuText"), COLOR_MENUTEXT}, {_t("Scrollbar"), COLOR_SCROLLBAR}, {_t("ThreeDDarkShadow"), COLOR_3DDKSHADOW}, {_t("ThreeDFace"), COLOR_3DFACE}, {_t("ThreeDHighlight"), COLOR_3DHILIGHT}, {_t("ThreeDLightShadow"), COLOR_3DLIGHT}, {_t("ThreeDShadow"), COLOR_3DSHADOW}, {_t("Window"), COLOR_WINDOW}, {_t("WindowFrame"), COLOR_WINDOWFRAME}, {_t("WindowText"), COLOR_WINDOWTEXT}}; - if (color == _t("Highlight")) - { - int iii = 0; - iii++; - } + if (color == _t("Highlight")) { + int iii = 0; + iii++; + } - for (auto& clr : colors) - { - if (!litehtml::t_strcasecmp(clr.name, color.c_str())) - { - litehtml::tchar_t str_clr[20]; - DWORD rgb_color = GetSysColor(clr.color_index); + for (auto& clr : colors) { + if (!litehtml::t_strcasecmp(clr.name, color.c_str())) { + litehtml::tchar_t str_clr[20]; + DWORD rgb_color = GetSysColor(clr.color_index); #ifdef LITEHTML_UTF8 - StringCchPrintfA(str_clr, 20, "#%02X%02X%02X", GetRValue(rgb_color), GetGValue(rgb_color), GetBValue(rgb_color)); + StringCchPrintfA(str_clr, 20, "#%02X%02X%02X", GetRValue(rgb_color), GetGValue(rgb_color), GetBValue(rgb_color)); #else - StringCchPrintf(str_clr, 20, L"#%02X%02X%02X", GetRValue(rgb_color), GetGValue(rgb_color), GetBValue(rgb_color)); -#endif // LITEHTML_UTF8 - return std::move(litehtml::tstring(str_clr)); - } + StringCchPrintf(str_clr, 20, L"#%02X%02X%02X", GetRValue(rgb_color), GetGValue(rgb_color), GetBValue(rgb_color)); +#endif // LITEHTML_UTF8 + return std::move(litehtml::tstring(str_clr)); } - return std::move(litehtml::tstring()); + } + return std::move(litehtml::tstring()); } diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_container.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_container.h index 2012c46a6..b2ca8e7e0 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_container.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_container.h @@ -1,110 +1,106 @@ #pragma once -#include -#include -#include +#include +#include +#include +#include #include #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include +#include + +#include #ifdef LITEHTML_UTF8 -#define t_make_url make_url_utf8 +#define t_make_url make_url_utf8 #else -#define t_make_url make_url +#define t_make_url make_url #endif -struct cairo_clip_box -{ - typedef std::vector vector; - litehtml::position box; - litehtml::border_radiuses radius; +struct cairo_clip_box { + typedef std::vector vector; + litehtml::position box; + litehtml::border_radiuses radius; - cairo_clip_box(const litehtml::position& vBox, litehtml::border_radiuses vRad) - { - box = vBox; - radius = vRad; - } + cairo_clip_box(const litehtml::position& vBox, litehtml::border_radiuses vRad) { + box = vBox; + radius = vRad; + } - cairo_clip_box(const cairo_clip_box& val) - { - box = val.box; - radius = val.radius; - } - cairo_clip_box& operator=(const cairo_clip_box& val) - { - box = val.box; - radius = val.radius; - return *this; - } + cairo_clip_box(const cairo_clip_box& val) { + box = val.box; + radius = val.radius; + } + cairo_clip_box& operator=(const cairo_clip_box& val) { + box = val.box; + radius = val.radius; + return *this; + } }; -class cairo_container : public litehtml::document_container -{ -public: - typedef std::shared_ptr image_ptr; - typedef std::map images_map; +class cairo_container : public litehtml::document_container { + public: + typedef std::shared_ptr image_ptr; + typedef std::map images_map; -protected: - cairo_surface_t* m_temp_surface; - cairo_t* m_temp_cr; - images_map m_images; - cairo_clip_box::vector m_clips; - IMLangFontLink2* m_font_link; - CRITICAL_SECTION m_img_sync; -public: - cairo_container(void); - virtual ~cairo_container(void); + protected: + cairo_surface_t* m_temp_surface; + cairo_t* m_temp_cr; + images_map m_images; + cairo_clip_box::vector m_clips; + IMLangFontLink2* m_font_link; + CRITICAL_SECTION m_img_sync; - virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; - virtual void delete_font(litehtml::uint_ptr hFont) override; - virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; - virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; + public: + cairo_container(void); + virtual ~cairo_container(void); - virtual int pt_to_px(int pt) const override; - virtual int get_default_font_size() const override; - virtual const litehtml::tchar_t* get_default_font_name() const override; - virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; - virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; - virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; - virtual void draw_image(litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos); - virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; - virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; + virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; + virtual void delete_font(litehtml::uint_ptr hFont) override; + virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; + virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; - virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; - virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; - virtual void del_clip() override; - virtual std::shared_ptr create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) override; - virtual void get_media_features(litehtml::media_features& media) const override; - virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; - virtual void link(const std::shared_ptr& doc, const litehtml::element::ptr& el) override; - virtual litehtml::tstring resolve_color(const litehtml::tstring& color) const override; + virtual int pt_to_px(int pt) const override; + virtual int get_default_font_size() const override; + virtual const litehtml::tchar_t* get_default_font_name() const override; + virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; + virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; + virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; + virtual void draw_image(litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos); + virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; + virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; + virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; + virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; + virtual void del_clip() override; + virtual std::shared_ptr create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) override; + virtual void get_media_features(litehtml::media_features& media) const override; + virtual void get_language(litehtml::tstring& language, litehtml::tstring& culture) const override; + virtual void link(const std::shared_ptr& doc, const litehtml::element::ptr& el) override; + virtual litehtml::tstring resolve_color(const litehtml::tstring& color) const override; - virtual void make_url( LPCWSTR url, LPCWSTR basepath, std::wstring& out ) = 0; - virtual image_ptr get_image(LPCWSTR url, bool redraw_on_ready) = 0; - void clear_images(); - void add_image(std::wstring& url, image_ptr& img); - void remove_image(std::wstring& url); - void make_url_utf8( const char* url, const char* basepath, std::wstring& out ); + virtual void make_url(LPCWSTR url, LPCWSTR basepath, std::wstring& out) = 0; + virtual image_ptr get_image(LPCWSTR url, bool redraw_on_ready) = 0; + void clear_images(); + void add_image(std::wstring& url, image_ptr& img); + void remove_image(std::wstring& url); + void make_url_utf8(const char* url, const char* basepath, std::wstring& out); -protected: - virtual void draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, double line_width); - virtual void fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color); - virtual void rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius ); + protected: + virtual void draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, double line_width); + virtual void fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color); + virtual void rounded_rectangle(cairo_t* cr, const litehtml::position& pos, const litehtml::border_radiuses& radius); - void set_color(cairo_t* cr, litehtml::web_color color) { cairo_set_source_rgba(cr, color.red / 255.0, color.green / 255.0, color.blue / 255.0, color.alpha / 255.0); } -private: - simpledib::dib* get_dib(litehtml::uint_ptr hdc) { return (simpledib::dib*) hdc; } - void apply_clip(cairo_t* cr); - bool add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg); + void set_color(cairo_t* cr, litehtml::web_color color) { cairo_set_source_rgba(cr, color.red / 255.0, color.green / 255.0, color.blue / 255.0, color.alpha / 255.0); } - void draw_txdib(cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy); - void lock_images_cache(); - void unlock_images_cache(); + private: + simpledib::dib* get_dib(litehtml::uint_ptr hdc) { return (simpledib::dib*)hdc; } + void apply_clip(cairo_t* cr); + bool add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg); + + void draw_txdib(cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy); + void lock_images_cache(); + void unlock_images_cache(); }; diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_font.cpp b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_font.cpp index 7a1bbe57c..adfab1e35 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_font.cpp +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_font.cpp @@ -1,379 +1,323 @@ #include "cairo_font.h" -cairo_font::cairo_font(IMLangFontLink2* fl, HFONT hFont, int size ) -{ - init(); - m_font_link = fl; - if(m_font_link) - { - m_font_link->AddRef(); - } - m_size = size; - set_font(hFont); +cairo_font::cairo_font(IMLangFontLink2* fl, HFONT hFont, int size) { + init(); + m_font_link = fl; + if (m_font_link) { + m_font_link->AddRef(); + } + m_size = size; + set_font(hFont); } -cairo_font::cairo_font(IMLangFontLink2* fl, LPCWSTR facename, int size, int weight, BOOL italic, BOOL strikeout, BOOL underline ) -{ - init(); - m_size = size; - m_font_link = fl; - if(m_font_link) - { - m_font_link->AddRef(); - } +cairo_font::cairo_font(IMLangFontLink2* fl, LPCWSTR facename, int size, int weight, BOOL italic, BOOL strikeout, BOOL underline) { + init(); + m_size = size; + m_font_link = fl; + if (m_font_link) { + m_font_link->AddRef(); + } - LOGFONT lf; - ZeroMemory(&lf, sizeof(lf)); - if(!lstrcmpi(facename, L"monospace")) - { - wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Courier New"); - } else if(!lstrcmpi(facename, L"serif")) - { - wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Times New Roman"); - } else if(!lstrcmpi(facename, L"sans-serif")) - { - wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Arial"); - } else if(!lstrcmpi(facename, L"fantasy")) - { - wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Impact"); - } else if(!lstrcmpi(facename, L"cursive")) - { - wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Comic Sans MS"); - } else - { - wcscpy_s(lf.lfFaceName, LF_FACESIZE, facename); - } + LOGFONT lf; + ZeroMemory(&lf, sizeof(lf)); + if (!lstrcmpi(facename, L"monospace")) { + wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Courier New"); + } else if (!lstrcmpi(facename, L"serif")) { + wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Times New Roman"); + } else if (!lstrcmpi(facename, L"sans-serif")) { + wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Arial"); + } else if (!lstrcmpi(facename, L"fantasy")) { + wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Impact"); + } else if (!lstrcmpi(facename, L"cursive")) { + wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Comic Sans MS"); + } else { + wcscpy_s(lf.lfFaceName, LF_FACESIZE, facename); + } - lf.lfHeight = -size; - lf.lfWeight = weight; - lf.lfItalic = italic; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfOutPrecision = OUT_DEFAULT_PRECIS; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - lf.lfStrikeOut = strikeout; - lf.lfUnderline = underline; + lf.lfHeight = -size; + lf.lfWeight = weight; + lf.lfItalic = italic; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfStrikeOut = strikeout; + lf.lfUnderline = underline; - HFONT fnt = CreateFontIndirect(&lf); - set_font(fnt); + HFONT fnt = CreateFontIndirect(&lf); + set_font(fnt); } -cairo_font::~cairo_font() -{ - if(m_font_face) - { - cairo_font_face_destroy(m_font_face); - } - for(size_t i = 0; i < m_linked_fonts.size(); i++) - { - if(m_linked_fonts[i]->hFont) - { - m_font_link->ReleaseFont(m_linked_fonts[i]->hFont); - } - if(m_linked_fonts[i]->font_face) - { - cairo_font_face_destroy(m_linked_fonts[i]->font_face); - } - } - m_linked_fonts.clear(); - if(m_font_link) - { - m_font_link->AddRef(); - } - if(m_hFont) - { - DeleteObject(m_hFont); - } +cairo_font::~cairo_font() { + if (m_font_face) { + cairo_font_face_destroy(m_font_face); + } + for (size_t i = 0; i < m_linked_fonts.size(); i++) { + if (m_linked_fonts[i]->hFont) { + m_font_link->ReleaseFont(m_linked_fonts[i]->hFont); + } + if (m_linked_fonts[i]->font_face) { + cairo_font_face_destroy(m_linked_fonts[i]->font_face); + } + } + m_linked_fonts.clear(); + if (m_font_link) { + m_font_link->AddRef(); + } + if (m_hFont) { + DeleteObject(m_hFont); + } } -void cairo_font::show_text( cairo_t* cr, int x, int y, const litehtml::tchar_t* str ) -{ - lock(); - text_chunk::vector chunks; - split_text(str, chunks); - cairo_set_font_size(cr, m_size); - cairo_move_to(cr, x, y); - for(size_t i = 0; i < chunks.size(); i++) - { - if(chunks[i]->font) - { - cairo_set_font_face(cr, chunks[i]->font->font_face); - } else - { - cairo_set_font_face(cr, m_font_face); - } - cairo_show_text(cr, chunks[i]->text); - } - unlock(); +void cairo_font::show_text(cairo_t* cr, int x, int y, const litehtml::tchar_t* str) { + lock(); + text_chunk::vector chunks; + split_text(str, chunks); + cairo_set_font_size(cr, m_size); + cairo_move_to(cr, x, y); + for (size_t i = 0; i < chunks.size(); i++) { + if (chunks[i]->font) { + cairo_set_font_face(cr, chunks[i]->font->font_face); + } else { + cairo_set_font_face(cr, m_font_face); + } + cairo_show_text(cr, chunks[i]->text); + } + unlock(); - if(m_bUnderline) - { - int tw = text_width(cr, chunks); + if (m_bUnderline) { + int tw = text_width(cr, chunks); - lock(); - cairo_set_line_width(cr, 1); - cairo_move_to(cr, x, y + 1.5); - cairo_line_to(cr, x + tw, y + 1.5); - cairo_stroke(cr); - unlock(); - } - if(m_bStrikeOut) - { - int tw = text_width(cr, chunks); + lock(); + cairo_set_line_width(cr, 1); + cairo_move_to(cr, x, y + 1.5); + cairo_line_to(cr, x + tw, y + 1.5); + cairo_stroke(cr); + unlock(); + } + if (m_bStrikeOut) { + int tw = text_width(cr, chunks); - cairo_font_metrics fm; - get_metrics(cr, &fm); + cairo_font_metrics fm; + get_metrics(cr, &fm); - int ln_y = y - fm.x_height / 2; + int ln_y = y - fm.x_height / 2; - lock(); - cairo_set_line_width(cr, 1); - cairo_move_to(cr, x, (double) ln_y - 0.5); - cairo_line_to(cr, x + tw, (double) ln_y - 0.5); - cairo_stroke(cr); - unlock(); - } + lock(); + cairo_set_line_width(cr, 1); + cairo_move_to(cr, x, (double)ln_y - 0.5); + cairo_line_to(cr, x + tw, (double)ln_y - 0.5); + cairo_stroke(cr); + unlock(); + } - free_text_chunks(chunks); + free_text_chunks(chunks); } -void cairo_font::split_text( const litehtml::tchar_t* src, text_chunk::vector& chunks ) -{ - wchar_t* str; +void cairo_font::split_text(const litehtml::tchar_t* src, text_chunk::vector& chunks) { + wchar_t* str; #ifdef LITEHTML_UTF8 - str = cairo_font::utf8_to_wchar(src); - wchar_t* str_start = str; + str = cairo_font::utf8_to_wchar(src); + wchar_t* str_start = str; #else - str = (wchar_t*) src; + str = (wchar_t*)src; #endif - int cch = lstrlen(str); + int cch = lstrlen(str); - HDC hdc = GetDC(NULL); - SelectObject(hdc, m_hFont); - HRESULT hr = S_OK; - while(cch > 0) - { - DWORD dwActualCodePages; - long cchActual; - if(m_font_link) - { - hr = m_font_link->GetStrCodePages(str, cch, m_font_code_pages, &dwActualCodePages, &cchActual); - } else - { - hr = S_FALSE; - } - - if(hr != S_OK) - { - break; - } - - text_chunk* chk = new text_chunk; + HDC hdc = GetDC(NULL); + SelectObject(hdc, m_hFont); + HRESULT hr = S_OK; + while (cch > 0) { + DWORD dwActualCodePages; + long cchActual; + if (m_font_link) { + hr = m_font_link->GetStrCodePages(str, cch, m_font_code_pages, &dwActualCodePages, &cchActual); + } else { + hr = S_FALSE; + } - int sz = WideCharToMultiByte(CP_UTF8, 0, str, cchActual, chk->text, 0, NULL, NULL) + 1; - chk->text = new CHAR[sz]; - sz = WideCharToMultiByte(CP_UTF8, 0, str, cchActual, chk->text, sz, NULL, NULL); - chk->text[sz] = 0; - chk->font = NULL; + if (hr != S_OK) { + break; + } - if(!(dwActualCodePages & m_font_code_pages)) - { - for(linked_font::vector::iterator i = m_linked_fonts.begin(); i != m_linked_fonts.end(); i++) - { - if((*i)->code_pages == dwActualCodePages) - { - chk->font = (*i); - break; - } - } - if(!chk->font) - { - linked_font* lkf = new linked_font; - lkf->code_pages = dwActualCodePages; - lkf->hFont = NULL; - m_font_link->MapFont(hdc, dwActualCodePages, 0, &lkf->hFont); - if (lkf->hFont) - { - lkf->font_face = create_font_face(lkf->hFont); - m_linked_fonts.push_back(lkf); - } - else - { - delete lkf; - lkf = NULL; - } - chk->font = lkf; - } - } + text_chunk* chk = new text_chunk; - chunks.push_back(chk); + int sz = WideCharToMultiByte(CP_UTF8, 0, str, cchActual, chk->text, 0, NULL, NULL) + 1; + chk->text = new CHAR[sz]; + sz = WideCharToMultiByte(CP_UTF8, 0, str, cchActual, chk->text, sz, NULL, NULL); + chk->text[sz] = 0; + chk->font = NULL; - cch -= cchActual; - str += cchActual; - } + if (!(dwActualCodePages & m_font_code_pages)) { + for (linked_font::vector::iterator i = m_linked_fonts.begin(); i != m_linked_fonts.end(); i++) { + if ((*i)->code_pages == dwActualCodePages) { + chk->font = (*i); + break; + } + } + if (!chk->font) { + linked_font* lkf = new linked_font; + lkf->code_pages = dwActualCodePages; + lkf->hFont = NULL; + m_font_link->MapFont(hdc, dwActualCodePages, 0, &lkf->hFont); + if (lkf->hFont) { + lkf->font_face = create_font_face(lkf->hFont); + m_linked_fonts.push_back(lkf); + } else { + delete lkf; + lkf = NULL; + } + chk->font = lkf; + } + } - if(hr != S_OK) - { - text_chunk* chk = new text_chunk; + chunks.push_back(chk); - int sz = WideCharToMultiByte(CP_UTF8, 0, str, -1, chk->text, 0, NULL, NULL) + 1; - chk->text = new CHAR[sz]; - sz = WideCharToMultiByte(CP_UTF8, 0, str, -1, chk->text, sz, NULL, NULL); - chk->text[sz] = 0; - chk->font = NULL; - chunks.push_back(chk); - } + cch -= cchActual; + str += cchActual; + } - ReleaseDC(NULL, hdc); + if (hr != S_OK) { + text_chunk* chk = new text_chunk; + + int sz = WideCharToMultiByte(CP_UTF8, 0, str, -1, chk->text, 0, NULL, NULL) + 1; + chk->text = new CHAR[sz]; + sz = WideCharToMultiByte(CP_UTF8, 0, str, -1, chk->text, sz, NULL, NULL); + chk->text[sz] = 0; + chk->font = NULL; + chunks.push_back(chk); + } + + ReleaseDC(NULL, hdc); #ifdef LITEHTML_UTF8 - delete str_start; + delete str_start; #endif } -void cairo_font::free_text_chunks( text_chunk::vector& chunks ) -{ - for(size_t i = 0; i < chunks.size(); i++) - { - delete chunks[i]; - } - chunks.clear(); +void cairo_font::free_text_chunks(text_chunk::vector& chunks) { + for (size_t i = 0; i < chunks.size(); i++) { + delete chunks[i]; + } + chunks.clear(); } -cairo_font_face_t* cairo_font::create_font_face( HFONT fnt ) -{ - LOGFONT lf; - GetObject(fnt, sizeof(LOGFONT), &lf); - return cairo_win32_font_face_create_for_logfontw(&lf); +cairo_font_face_t* cairo_font::create_font_face(HFONT fnt) { + LOGFONT lf; + GetObject(fnt, sizeof(LOGFONT), &lf); + return cairo_win32_font_face_create_for_logfontw(&lf); } -int cairo_font::text_width( cairo_t* cr, const litehtml::tchar_t* str ) -{ - text_chunk::vector chunks; - split_text(str, chunks); +int cairo_font::text_width(cairo_t* cr, const litehtml::tchar_t* str) { + text_chunk::vector chunks; + split_text(str, chunks); - int ret = text_width(cr, chunks); + int ret = text_width(cr, chunks); - free_text_chunks(chunks); + free_text_chunks(chunks); - return (int) ret; + return (int)ret; } -int cairo_font::text_width( cairo_t* cr, text_chunk::vector& chunks ) -{ - lock(); - cairo_set_font_size(cr, m_size); - double ret = 0; - for(size_t i = 0; i < chunks.size(); i++) - { - if(chunks[i]->font) - { - cairo_set_font_face(cr, chunks[i]->font->font_face); - } else - { - cairo_set_font_face(cr, m_font_face); - } - cairo_text_extents_t ext; - cairo_text_extents(cr, chunks[i]->text, &ext); - ret += ext.x_advance; - } - unlock(); +int cairo_font::text_width(cairo_t* cr, text_chunk::vector& chunks) { + lock(); + cairo_set_font_size(cr, m_size); + double ret = 0; + for (size_t i = 0; i < chunks.size(); i++) { + if (chunks[i]->font) { + cairo_set_font_face(cr, chunks[i]->font->font_face); + } else { + cairo_set_font_face(cr, m_font_face); + } + cairo_text_extents_t ext; + cairo_text_extents(cr, chunks[i]->text, &ext); + ret += ext.x_advance; + } + unlock(); - return (int) ret; + return (int)ret; } -void cairo_font::get_metrics(cairo_t* cr, cairo_font_metrics* fm ) -{ - lock(); - cairo_set_font_face(cr, m_font_face); - cairo_set_font_size(cr, m_size); - cairo_font_extents_t ext; - cairo_font_extents(cr, &ext); +void cairo_font::get_metrics(cairo_t* cr, cairo_font_metrics* fm) { + lock(); + cairo_set_font_face(cr, m_font_face); + cairo_set_font_size(cr, m_size); + cairo_font_extents_t ext; + cairo_font_extents(cr, &ext); - cairo_text_extents_t tex; - cairo_text_extents(cr, "x", &tex); + cairo_text_extents_t tex; + cairo_text_extents(cr, "x", &tex); - fm->ascent = (int) ext.ascent; - fm->descent = (int) ext.descent; - fm->height = (int) (ext.ascent + ext.descent); - fm->x_height = (int) tex.height; - unlock(); + fm->ascent = (int)ext.ascent; + fm->descent = (int)ext.descent; + fm->height = (int)(ext.ascent + ext.descent); + fm->x_height = (int)tex.height; + unlock(); } -void cairo_font::set_font( HFONT hFont ) -{ - clear(); +void cairo_font::set_font(HFONT hFont) { + clear(); - m_hFont = hFont; - m_font_face = create_font_face(m_hFont); - m_font_code_pages = 0; - if(m_font_link) - { - HDC hdc = GetDC(NULL); - SelectObject(hdc, m_hFont); - m_font_link->GetFontCodePages(hdc, m_hFont, &m_font_code_pages); - ReleaseDC(NULL, hdc); - } - LOGFONT lf; - GetObject(m_hFont, sizeof(LOGFONT), &lf); - m_bUnderline = lf.lfUnderline; - m_bStrikeOut = lf.lfStrikeOut; + m_hFont = hFont; + m_font_face = create_font_face(m_hFont); + m_font_code_pages = 0; + if (m_font_link) { + HDC hdc = GetDC(NULL); + SelectObject(hdc, m_hFont); + m_font_link->GetFontCodePages(hdc, m_hFont, &m_font_code_pages); + ReleaseDC(NULL, hdc); + } + LOGFONT lf; + GetObject(m_hFont, sizeof(LOGFONT), &lf); + m_bUnderline = lf.lfUnderline; + m_bStrikeOut = lf.lfStrikeOut; } -void cairo_font::clear() -{ - if(m_font_face) - { - cairo_font_face_destroy(m_font_face); - m_font_face = NULL; - } - for(size_t i = 0; i < m_linked_fonts.size(); i++) - { - if(m_linked_fonts[i]->hFont && m_font_link) - { - m_font_link->ReleaseFont(m_linked_fonts[i]->hFont); - } - if(m_linked_fonts[i]->font_face) - { - cairo_font_face_destroy(m_linked_fonts[i]->font_face); - } - } - m_linked_fonts.clear(); - if(m_hFont) - { - DeleteObject(m_hFont); - m_hFont = NULL; - } +void cairo_font::clear() { + if (m_font_face) { + cairo_font_face_destroy(m_font_face); + m_font_face = NULL; + } + for (size_t i = 0; i < m_linked_fonts.size(); i++) { + if (m_linked_fonts[i]->hFont && m_font_link) { + m_font_link->ReleaseFont(m_linked_fonts[i]->hFont); + } + if (m_linked_fonts[i]->font_face) { + cairo_font_face_destroy(m_linked_fonts[i]->font_face); + } + } + m_linked_fonts.clear(); + if (m_hFont) { + DeleteObject(m_hFont); + m_hFont = NULL; + } } -void cairo_font::init() -{ - m_hFont = NULL; - m_font_face = NULL; - m_font_link = NULL; - m_font_code_pages = 0; - m_size = 0; - m_bUnderline = FALSE; - m_bStrikeOut = FALSE; +void cairo_font::init() { + m_hFont = NULL; + m_font_face = NULL; + m_font_link = NULL; + m_font_code_pages = 0; + m_size = 0; + m_bUnderline = FALSE; + m_bStrikeOut = FALSE; } -wchar_t* cairo_font::utf8_to_wchar( const char* src ) -{ - if(!src) return NULL; +wchar_t* cairo_font::utf8_to_wchar(const char* src) { + if (!src) return NULL; - int len = (int) strlen(src); - wchar_t* ret = new wchar_t[len + 1]; - MultiByteToWideChar(CP_UTF8, 0, src, -1, ret, len + 1); - return ret; + int len = (int)strlen(src); + wchar_t* ret = new wchar_t[len + 1]; + MultiByteToWideChar(CP_UTF8, 0, src, -1, ret, len + 1); + return ret; } -char* cairo_font::wchar_to_utf8( const wchar_t* src ) -{ - if(!src) return NULL; +char* cairo_font::wchar_to_utf8(const wchar_t* src) { + if (!src) return NULL; - int len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL); - char* ret = new char[len]; - WideCharToMultiByte(CP_UTF8, 0, src, -1, ret, len, NULL, NULL); - return ret; + int len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL); + char* ret = new char[len]; + WideCharToMultiByte(CP_UTF8, 0, src, -1, ret, len, NULL, NULL); + return ret; } \ No newline at end of file diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_font.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_font.h index a1fa21204..385c3ad34 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_font.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/cairo/cairo_font.h @@ -1,117 +1,99 @@ #pragma once -#include -#include +#include +#include +#include #include #include -#include #include +#include +#include +#include + #include -#include -#include -#include -struct linked_font -{ - typedef std::vector vector; +struct linked_font { + typedef std::vector vector; - DWORD code_pages; - HFONT hFont; - cairo_font_face_t* font_face; + DWORD code_pages; + HFONT hFont; + cairo_font_face_t* font_face; }; -struct text_chunk -{ - typedef std::vector vector; +struct text_chunk { + typedef std::vector vector; - char* text; - linked_font* font; + char* text; + linked_font* font; - ~text_chunk() - { - if(text) - { - delete text; - } - } + ~text_chunk() { + if (text) { + delete text; + } + } }; -struct cairo_font_metrics -{ - int height; - int ascent; - int descent; - int x_height; +struct cairo_font_metrics { + int height; + int ascent; + int descent; + int x_height; }; +class cairo_font { + HFONT m_hFont; + cairo_font_face_t* m_font_face; + IMLangFontLink2* m_font_link; + DWORD m_font_code_pages; + linked_font::vector m_linked_fonts; + int m_size; + BOOL m_bUnderline; + BOOL m_bStrikeOut; + cairo_font_metrics m_metrics; -class cairo_font -{ - HFONT m_hFont; - cairo_font_face_t* m_font_face; - IMLangFontLink2* m_font_link; - DWORD m_font_code_pages; - linked_font::vector m_linked_fonts; - int m_size; - BOOL m_bUnderline; - BOOL m_bStrikeOut; - cairo_font_metrics m_metrics; -public: - // fonts are not thread safe :( - // you have to declare and initialize cairo_font::m_sync before the first using. - static CRITICAL_SECTION m_sync; + public: + // fonts are not thread safe :( + // you have to declare and initialize cairo_font::m_sync before the first using. + static CRITICAL_SECTION m_sync; - cairo_font(IMLangFontLink2* fl, HFONT hFont, int size); - cairo_font(IMLangFontLink2* fl, LPCWSTR facename, int size, int weight, BOOL italic, BOOL strikeout, BOOL underline); + cairo_font(IMLangFontLink2* fl, HFONT hFont, int size); + cairo_font(IMLangFontLink2* fl, LPCWSTR facename, int size, int weight, BOOL italic, BOOL strikeout, BOOL underline); - void init(); - ~cairo_font(); + void init(); + ~cairo_font(); - void show_text(cairo_t* cr, int x, int y, const litehtml::tchar_t*); - int text_width(cairo_t* cr, const litehtml::tchar_t* str); - void load_metrics(cairo_t* cr); - cairo_font_metrics& metrics(); - static wchar_t* utf8_to_wchar(const char* src); - static char* wchar_to_utf8(const wchar_t* src); -private: - void split_text(const litehtml::tchar_t* str, text_chunk::vector& chunks); - void free_text_chunks(text_chunk::vector& chunks); - cairo_font_face_t* create_font_face(HFONT fnt); - void set_font(HFONT hFont); - void clear(); - int text_width(cairo_t* cr, text_chunk::vector& chunks); - void lock(); - void unlock(); - int round_d(double val); - void get_metrics(cairo_t* cr, cairo_font_metrics* fm); + void show_text(cairo_t* cr, int x, int y, const litehtml::tchar_t*); + int text_width(cairo_t* cr, const litehtml::tchar_t* str); + void load_metrics(cairo_t* cr); + cairo_font_metrics& metrics(); + static wchar_t* utf8_to_wchar(const char* src); + static char* wchar_to_utf8(const wchar_t* src); + + private: + void split_text(const litehtml::tchar_t* str, text_chunk::vector& chunks); + void free_text_chunks(text_chunk::vector& chunks); + cairo_font_face_t* create_font_face(HFONT fnt); + void set_font(HFONT hFont); + void clear(); + int text_width(cairo_t* cr, text_chunk::vector& chunks); + void lock(); + void unlock(); + int round_d(double val); + void get_metrics(cairo_t* cr, cairo_font_metrics* fm); }; -inline void cairo_font::lock() -{ - EnterCriticalSection(&m_sync); +inline void cairo_font::lock() { EnterCriticalSection(&m_sync); } + +inline void cairo_font::unlock() { LeaveCriticalSection(&m_sync); } + +inline int cairo_font::round_d(double val) { + int int_val = (int)val; + if (val - int_val >= 0.5) { + int_val++; + } + return int_val; } -inline void cairo_font::unlock() -{ - LeaveCriticalSection(&m_sync); -} +inline cairo_font_metrics& cairo_font::metrics() { return m_metrics; } -inline int cairo_font::round_d(double val) -{ - int int_val = (int) val; - if(val - int_val >= 0.5) - { - int_val++; - } - return int_val; -} - -inline cairo_font_metrics& cairo_font::metrics() -{ - return m_metrics; -} - -inline void cairo_font::load_metrics(cairo_t* cr) -{ - get_metrics(cr, &m_metrics); -} +inline void cairo_font::load_metrics(cairo_t* cr) { get_metrics(cr, &m_metrics); } diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/gdiplus/gdiplus_container.cpp b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/gdiplus/gdiplus_container.cpp index d0c374e53..5cc1ea1d2 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/gdiplus/gdiplus_container.cpp +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/gdiplus/gdiplus_container.cpp @@ -1,198 +1,159 @@ #include "gdiplus_container.h" -gdiplus_container::gdiplus_container(void) -{ +gdiplus_container::gdiplus_container(void) {} + +gdiplus_container::~gdiplus_container(void) {} + +void gdiplus_container::draw_ellipse(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, int line_width) { + Gdiplus::Graphics graphics(hdc); + Gdiplus::LinearGradientBrush* brush = NULL; + + graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality); + graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + + Gdiplus::Pen pen(Gdiplus::Color(color.alpha, color.red, color.green, color.blue)); + graphics.DrawEllipse(&pen, x, y, width, height); } -gdiplus_container::~gdiplus_container(void) -{ +void gdiplus_container::fill_ellipse(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color) { + Gdiplus::Graphics graphics(hdc); + + graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality); + graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + + Gdiplus::SolidBrush brush(Gdiplus::Color(color.alpha, color.red, color.green, color.blue)); + graphics.FillEllipse(&brush, x, y, width, height); } -void gdiplus_container::draw_ellipse( HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, int line_width ) -{ - Gdiplus::Graphics graphics(hdc); - Gdiplus::LinearGradientBrush* brush = NULL; +void gdiplus_container::fill_rect(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, const litehtml::css_border_radius& radius) { + Gdiplus::Graphics graphics(hdc); - graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality); - graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); - - Gdiplus::Pen pen( Gdiplus::Color(color.alpha, color.red, color.green, color.blue) ); - graphics.DrawEllipse(&pen, x, y, width, height); + Gdiplus::SolidBrush brush(Gdiplus::Color(color.alpha, color.red, color.green, color.blue)); + graphics.FillRectangle(&brush, x, y, width, height); } -void gdiplus_container::fill_ellipse( HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color ) -{ - Gdiplus::Graphics graphics(hdc); - - graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality); - graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); - - Gdiplus::SolidBrush brush( Gdiplus::Color(color.alpha, color.red, color.green, color.blue) ); - graphics.FillEllipse(&brush, x, y, width, height); +void gdiplus_container::get_img_size(litehtml::uint_ptr img, litehtml::size& sz) { + Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*)img; + if (bmp) { + sz.width = bmp->GetWidth(); + sz.height = bmp->GetHeight(); + } } -void gdiplus_container::fill_rect( HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, const litehtml::css_border_radius& radius ) -{ - Gdiplus::Graphics graphics(hdc); - - Gdiplus::SolidBrush brush( Gdiplus::Color(color.alpha, color.red, color.green, color.blue) ); - graphics.FillRectangle(&brush, x, y, width, height); +void gdiplus_container::draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos) { + Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*)img; + if (bmp) { + Gdiplus::Graphics graphics(hdc); + graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); + graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); + graphics.DrawImage(bmp, pos.x, pos.y, pos.width, pos.height); + } } -void gdiplus_container::get_img_size( litehtml::uint_ptr img, litehtml::size& sz ) -{ - Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*) img; - if(bmp) - { - sz.width = bmp->GetWidth(); - sz.height = bmp->GetHeight(); - } +void gdiplus_container::free_image(litehtml::uint_ptr img) { + Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*)img; + if (bmp) { + delete bmp; + } } -void gdiplus_container::draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos ) -{ - Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*) img; - if(bmp) - { - Gdiplus::Graphics graphics(hdc); - graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); - graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); - graphics.DrawImage(bmp, pos.x, pos.y, pos.width, pos.height); - } +void gdiplus_container::draw_img_bg(HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment) { + Gdiplus::Bitmap* bgbmp = (Gdiplus::Bitmap*)img; + + int img_width = bgbmp->GetWidth(); + int img_height = bgbmp->GetHeight(); + + Gdiplus::Graphics graphics(hdc); + graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); + graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); + + Gdiplus::Region reg(Gdiplus::Rect(draw_pos.left(), draw_pos.top(), draw_pos.width, draw_pos.height)); + graphics.SetClip(®); + + switch (repeat) { + case litehtml::background_repeat_no_repeat: { + graphics.DrawImage(bgbmp, pos.x, pos.y, bgbmp->GetWidth(), bgbmp->GetHeight()); + } break; + case litehtml::background_repeat_repeat_x: { + Gdiplus::CachedBitmap bmp(bgbmp, &graphics); + for (int x = pos.left(); x < pos.right(); x += bgbmp->GetWidth()) { + graphics.DrawCachedBitmap(&bmp, x, pos.top()); + } + + for (int x = pos.left() - bgbmp->GetWidth(); x + (int)bgbmp->GetWidth() > draw_pos.left(); x -= bgbmp->GetWidth()) { + graphics.DrawCachedBitmap(&bmp, x, pos.top()); + } + } break; + case litehtml::background_repeat_repeat_y: { + Gdiplus::CachedBitmap bmp(bgbmp, &graphics); + for (int y = pos.top(); y < pos.bottom(); y += bgbmp->GetHeight()) { + graphics.DrawCachedBitmap(&bmp, pos.left(), y); + } + + for (int y = pos.top() - bgbmp->GetHeight(); y + (int)bgbmp->GetHeight() > draw_pos.top(); y -= bgbmp->GetHeight()) { + graphics.DrawCachedBitmap(&bmp, pos.left(), y); + } + } break; + case litehtml::background_repeat_repeat: { + Gdiplus::CachedBitmap bmp(bgbmp, &graphics); + if (bgbmp->GetHeight() >= 0) { + for (int x = pos.left(); x < pos.right(); x += bgbmp->GetWidth()) { + for (int y = pos.top(); y < pos.bottom(); y += bgbmp->GetHeight()) { + graphics.DrawCachedBitmap(&bmp, x, y); + } + } + } + } break; + } } -void gdiplus_container::free_image( litehtml::uint_ptr img ) -{ - Gdiplus::Bitmap* bmp = (Gdiplus::Bitmap*) img; - if(bmp) - { - delete bmp; - } -} - -void gdiplus_container::draw_img_bg( HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment ) -{ - Gdiplus::Bitmap* bgbmp = (Gdiplus::Bitmap*) img; - - int img_width = bgbmp->GetWidth(); - int img_height = bgbmp->GetHeight(); - - Gdiplus::Graphics graphics(hdc); - graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); - graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); - - Gdiplus::Region reg(Gdiplus::Rect(draw_pos.left(), draw_pos.top(), draw_pos.width, draw_pos.height)); - graphics.SetClip(®); - - switch(repeat) - { - case litehtml::background_repeat_no_repeat: - { - graphics.DrawImage(bgbmp, pos.x, pos.y, bgbmp->GetWidth(), bgbmp->GetHeight()); - } - break; - case litehtml::background_repeat_repeat_x: - { - Gdiplus::CachedBitmap bmp(bgbmp, &graphics); - for(int x = pos.left(); x < pos.right(); x += bgbmp->GetWidth()) - { - graphics.DrawCachedBitmap(&bmp, x, pos.top()); - } - - for(int x = pos.left() - bgbmp->GetWidth(); x + (int) bgbmp->GetWidth() > draw_pos.left(); x -= bgbmp->GetWidth()) - { - graphics.DrawCachedBitmap(&bmp, x, pos.top()); - } - } - break; - case litehtml::background_repeat_repeat_y: - { - Gdiplus::CachedBitmap bmp(bgbmp, &graphics); - for(int y = pos.top(); y < pos.bottom(); y += bgbmp->GetHeight()) - { - graphics.DrawCachedBitmap(&bmp, pos.left(), y); - } - - for(int y = pos.top() - bgbmp->GetHeight(); y + (int) bgbmp->GetHeight() > draw_pos.top(); y -= bgbmp->GetHeight()) - { - graphics.DrawCachedBitmap(&bmp, pos.left(), y); - } - } - break; - case litehtml::background_repeat_repeat: - { - Gdiplus::CachedBitmap bmp(bgbmp, &graphics); - if(bgbmp->GetHeight() >= 0) - { - for(int x = pos.left(); x < pos.right(); x += bgbmp->GetWidth()) - { - for(int y = pos.top(); y < pos.bottom(); y += bgbmp->GetHeight()) - { - graphics.DrawCachedBitmap(&bmp, x, y); - } - } - } - } - break; - } -} - -void gdiplus_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos ) -{ - apply_clip((HDC) hdc); - - // draw left border - if(borders.left.width.val() != 0 && borders.left.style > litehtml::border_style_hidden) - { - HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.left.color.red, borders.left.color.green, borders.left.color.blue)); - HPEN oldPen = (HPEN) SelectObject((HDC) hdc, pen); - for(int x = 0; x < borders.left.width.val(); x++) - { - MoveToEx((HDC) hdc, draw_pos.left() + x, draw_pos.top(), NULL); - LineTo((HDC) hdc, draw_pos.left() + x, draw_pos.bottom()); - } - SelectObject((HDC) hdc, oldPen); - DeleteObject(pen); - } - // draw right border - if(borders.right.width.val() != 0 && borders.right.style > litehtml::border_style_hidden) - { - HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.right.color.red, borders.right.color.green, borders.right.color.blue)); - HPEN oldPen = (HPEN) SelectObject((HDC) hdc, pen); - for(int x = 0; x < borders.right.width.val(); x++) - { - MoveToEx((HDC) hdc, draw_pos.right() - x - 1, draw_pos.top(), NULL); - LineTo((HDC) hdc, draw_pos.right() - x - 1, draw_pos.bottom()); - } - SelectObject((HDC) hdc, oldPen); - DeleteObject(pen); - } - // draw top border - if(borders.top.width.val() != 0 && borders.top.style > litehtml::border_style_hidden) - { - HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.top.color.red, borders.top.color.green, borders.top.color.blue)); - HPEN oldPen = (HPEN) SelectObject((HDC) hdc, pen); - for(int y = 0; y < borders.top.width.val(); y++) - { - MoveToEx((HDC) hdc, draw_pos.left(), draw_pos.top() + y, NULL); - LineTo((HDC) hdc, draw_pos.right(), draw_pos.top() + y); - } - SelectObject((HDC) hdc, oldPen); - DeleteObject(pen); - } - // draw bottom border - if(borders.bottom.width.val() != 0 && borders.bottom.style > litehtml::border_style_hidden) - { - HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.bottom.color.red, borders.bottom.color.green, borders.bottom.color.blue)); - HPEN oldPen = (HPEN) SelectObject((HDC) hdc, pen); - for(int y = 0; y < borders.bottom.width.val(); y++) - { - MoveToEx((HDC) hdc, draw_pos.left(), draw_pos.bottom() - y - 1, NULL); - LineTo((HDC) hdc, draw_pos.right(), draw_pos.bottom() - y - 1); - } - SelectObject((HDC) hdc, oldPen); - DeleteObject(pen); - } - - release_clip((HDC) hdc); +void gdiplus_container::draw_borders(litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos) { + apply_clip((HDC)hdc); + + // draw left border + if (borders.left.width.val() != 0 && borders.left.style > litehtml::border_style_hidden) { + HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.left.color.red, borders.left.color.green, borders.left.color.blue)); + HPEN oldPen = (HPEN)SelectObject((HDC)hdc, pen); + for (int x = 0; x < borders.left.width.val(); x++) { + MoveToEx((HDC)hdc, draw_pos.left() + x, draw_pos.top(), NULL); + LineTo((HDC)hdc, draw_pos.left() + x, draw_pos.bottom()); + } + SelectObject((HDC)hdc, oldPen); + DeleteObject(pen); + } + // draw right border + if (borders.right.width.val() != 0 && borders.right.style > litehtml::border_style_hidden) { + HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.right.color.red, borders.right.color.green, borders.right.color.blue)); + HPEN oldPen = (HPEN)SelectObject((HDC)hdc, pen); + for (int x = 0; x < borders.right.width.val(); x++) { + MoveToEx((HDC)hdc, draw_pos.right() - x - 1, draw_pos.top(), NULL); + LineTo((HDC)hdc, draw_pos.right() - x - 1, draw_pos.bottom()); + } + SelectObject((HDC)hdc, oldPen); + DeleteObject(pen); + } + // draw top border + if (borders.top.width.val() != 0 && borders.top.style > litehtml::border_style_hidden) { + HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.top.color.red, borders.top.color.green, borders.top.color.blue)); + HPEN oldPen = (HPEN)SelectObject((HDC)hdc, pen); + for (int y = 0; y < borders.top.width.val(); y++) { + MoveToEx((HDC)hdc, draw_pos.left(), draw_pos.top() + y, NULL); + LineTo((HDC)hdc, draw_pos.right(), draw_pos.top() + y); + } + SelectObject((HDC)hdc, oldPen); + DeleteObject(pen); + } + // draw bottom border + if (borders.bottom.width.val() != 0 && borders.bottom.style > litehtml::border_style_hidden) { + HPEN pen = CreatePen(PS_SOLID, 1, RGB(borders.bottom.color.red, borders.bottom.color.green, borders.bottom.color.blue)); + HPEN oldPen = (HPEN)SelectObject((HDC)hdc, pen); + for (int y = 0; y < borders.bottom.width.val(); y++) { + MoveToEx((HDC)hdc, draw_pos.left(), draw_pos.bottom() - y - 1, NULL); + LineTo((HDC)hdc, draw_pos.right(), draw_pos.bottom() - y - 1); + } + SelectObject((HDC)hdc, oldPen); + DeleteObject(pen); + } + + release_clip((HDC)hdc); } diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/gdiplus/gdiplus_container.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/gdiplus/gdiplus_container.h index c6d607a23..138b8ab1c 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/gdiplus/gdiplus_container.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/gdiplus/gdiplus_container.h @@ -1,29 +1,29 @@ #pragma once -#include -#include -#include +#include +#include #include #include -#include #include +#include +#include +#include + #include -#include -#include + #include "..\win32\win32_container.h" -class gdiplus_container : public litehtml::win32_container -{ -public: - gdiplus_container(void); - virtual ~gdiplus_container(void); +class gdiplus_container : public litehtml::win32_container { + public: + gdiplus_container(void); + virtual ~gdiplus_container(void); -protected: - virtual void draw_ellipse(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, int line_width); - virtual void fill_ellipse(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color); - virtual void fill_rect(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, const litehtml::css_border_radius& radius); - virtual void get_img_size(litehtml::uint_ptr img, litehtml::size& sz); - virtual void draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos); - virtual void free_image(litehtml::uint_ptr img); - virtual void draw_img_bg(HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment); - virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos); + protected: + virtual void draw_ellipse(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, int line_width); + virtual void fill_ellipse(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color); + virtual void fill_rect(HDC hdc, int x, int y, int width, int height, const litehtml::web_color& color, const litehtml::css_border_radius& radius); + virtual void get_img_size(litehtml::uint_ptr img, litehtml::size& sz); + virtual void draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos); + virtual void free_image(litehtml::uint_ptr img); + virtual void draw_img_bg(HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment); + virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos); }; diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/haiku/container_haiku.cpp b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/haiku/container_haiku.cpp index e919a6d63..790074a01 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/haiku/container_haiku.cpp +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/haiku/container_haiku.cpp @@ -6,563 +6,425 @@ */ #include "container_haiku.h" -#include -#include -#include -#include -#include - #include -#include #include #include +#include #include -LiteHtmlView::LiteHtmlView(BRect frame, const char *name) - : BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW), - fContext(NULL), - m_html(NULL), - m_images(), - m_base_url(), - m_url() -{ - - BRect bounds(Bounds()); - BPoint topLeft = bounds.LeftTop(); - std::cout << "Initial bounds: topLeft x: " << +topLeft.x << ", y: " - << +topLeft.y << ", width: " << +bounds.Width() << ", height: " - << +bounds.Height() << std::endl; - - SetDrawingMode(B_OP_OVER); - SetFont(be_plain_font); - - //FillRect(bounds,B_SOLID_LOW); - - //SetLowColor(B_DOCUMENT_PANEL_COLOR); - //FillRect(rect); +#include +#include +#include +#include +#include + +LiteHtmlView::LiteHtmlView(BRect frame, const char* name) : BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW), fContext(NULL), m_html(NULL), m_images(), m_base_url(), m_url() { + BRect bounds(Bounds()); + BPoint topLeft = bounds.LeftTop(); + std::cout << "Initial bounds: topLeft x: " << +topLeft.x << ", y: " << +topLeft.y << ", width: " << +bounds.Width() << ", height: " << +bounds.Height() << std::endl; + + SetDrawingMode(B_OP_OVER); + SetFont(be_plain_font); + + // FillRect(bounds,B_SOLID_LOW); + + // SetLowColor(B_DOCUMENT_PANEL_COLOR); + // FillRect(rect); } -LiteHtmlView::~LiteHtmlView() -{ +LiteHtmlView::~LiteHtmlView() {} + +void LiteHtmlView::SetContext(litehtml::context* ctx) { fContext = ctx; } + +void LiteHtmlView::RenderFile(const char* localFilePath) { + std::cout << "RenderFile" << std::endl; + // BUrlRequest req; + // assume a local file for now, that is HTML + std::ifstream t(localFilePath); + std::string html((std::istreambuf_iterator(t)), std::istreambuf_iterator()); + + // std::cout << "HTML output:-" << std::endl << html << std::endl; + + // Get parent folder for the base url + std::cout << "Loaded from file: " << localFilePath << std::endl; + BPath htmlPath(localFilePath); + BPath dirPath; + htmlPath.GetParent(&dirPath); + std::cout << "parent path: " << dirPath.Path() << std::endl; + set_base_url(dirPath.Path()); + // std::cout << " base url now:" << m_base_url << std::endl; + + RenderHTML(html); } -void -LiteHtmlView::SetContext(litehtml::context* ctx) -{ - fContext = ctx; +void LiteHtmlView::RenderHTML(const std::string& htmlText) { + std::cout << "RenderHTML" << std::endl; + + // now use this string + m_html = litehtml::document::createFromString(htmlText.c_str(), this, fContext); + if (m_html) { + std::cout << "Successfully read html" << std::endl; + // success + // post-parse render operations, if required. + Invalidate(); + } else { + std::cout << "Failed to read html" << std::endl; + } + // always fire the rendering complete message + std::cout << "Sending html rendered message: " << M_HTML_RENDERED << std::endl; } -void -LiteHtmlView::RenderFile(const char* localFilePath) -{ - std::cout << "RenderFile" << std::endl; - //BUrlRequest req; - // assume a local file for now, that is HTML - std::ifstream t(localFilePath); - std::string html((std::istreambuf_iterator(t)), - std::istreambuf_iterator()); - - //std::cout << "HTML output:-" << std::endl << html << std::endl; - - // Get parent folder for the base url - std::cout << "Loaded from file: " << localFilePath << std::endl; - BPath htmlPath(localFilePath); - BPath dirPath; - htmlPath.GetParent(&dirPath); - std::cout << "parent path: " << dirPath.Path() << std::endl; - set_base_url(dirPath.Path()); - //std::cout << " base url now:" << m_base_url << std::endl; - - RenderHTML(html); +void LiteHtmlView::Draw(BRect b) { + std::cout << "DRAW CALLED" << std::endl; + + BRect bounds(Bounds()); + FillRect(bounds, B_SOLID_LOW); + + // b only part of the window, but we need to draw the whole lot + + if (NULL != m_html) { + BPoint leftTop = bounds.LeftTop(); + litehtml::position clip(leftTop.x, leftTop.y, bounds.Width(), bounds.Height()); + m_html->render(bounds.Width()); + m_html->draw((litehtml::uint_ptr)this, 0, 0, &clip); + } + SendNotices(M_HTML_RENDERED, new BMessage(M_HTML_RENDERED)); } -void -LiteHtmlView::RenderHTML(const std::string& htmlText) -{ - std::cout << "RenderHTML" << std::endl; - - // now use this string - m_html = litehtml::document::createFromString( - htmlText.c_str(), this, fContext); - if (m_html) - { - std::cout << "Successfully read html" << std::endl; - // success - // post-parse render operations, if required. - Invalidate(); - } else { - std::cout << "Failed to read html" << std::endl; - } - // always fire the rendering complete message - std::cout << "Sending html rendered message: " << M_HTML_RENDERED << std::endl; +void LiteHtmlView::GetPreferredSize(float* width, float* height) { + if (NULL == m_html) { + BRect bounds(Bounds()); + *width = bounds.Width(); + *height = bounds.Height(); + } else { + *width = m_html->width(); + *height = m_html->height(); + } } -void -LiteHtmlView::Draw(BRect b) -{ - std::cout << "DRAW CALLED" << std::endl; - - BRect bounds(Bounds()); - FillRect(bounds,B_SOLID_LOW); - - // b only part of the window, but we need to draw the whole lot - - if (NULL != m_html) { - BPoint leftTop = bounds.LeftTop(); - litehtml::position clip(leftTop.x,leftTop.y, - bounds.Width(),bounds.Height()); - m_html->render(bounds.Width()); - m_html->draw((litehtml::uint_ptr) this,0,0,&clip); - } - SendNotices(M_HTML_RENDERED,new BMessage(M_HTML_RENDERED)); -} +litehtml::uint_ptr LiteHtmlView::create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) { + // std::cout << "create_font" << std::endl; + litehtml::string_vector fonts; + litehtml::split_string(faceName, fonts, ","); + litehtml::trim(fonts[0]); -void -LiteHtmlView::GetPreferredSize(float* width,float* height) -{ - if (NULL == m_html) - { - BRect bounds(Bounds()); - *width = bounds.Width(); - *height = bounds.Height(); - } else { - *width = m_html->width(); - *height = m_html->height(); - } -} - -litehtml::uint_ptr -LiteHtmlView::create_font( const litehtml::tchar_t* faceName, int size, - int weight, litehtml::font_style italic, unsigned int decoration, - litehtml::font_metrics* fm ) -{ - //std::cout << "create_font" << std::endl; - litehtml::string_vector fonts; - litehtml::split_string(faceName, fonts, ","); - litehtml::trim(fonts[0]); - - uint16 face = B_REGULAR_FACE; // default - if (italic == litehtml::fontStyleItalic) - { - face |= B_ITALIC_FACE; - } - if (decoration & litehtml::font_decoration_underline) - { - face |= B_UNDERSCORE_FACE; - } - if (decoration & litehtml::font_decoration_linethrough) - { - face |= B_STRIKEOUT_FACE; - } - // Note: LIGHT, HEAVY, CONDENSED not supported in BeOS R5 + uint16 face = B_REGULAR_FACE; // default + if (italic == litehtml::fontStyleItalic) { + face |= B_ITALIC_FACE; + } + if (decoration & litehtml::font_decoration_underline) { + face |= B_UNDERSCORE_FACE; + } + if (decoration & litehtml::font_decoration_linethrough) { + face |= B_STRIKEOUT_FACE; + } + // Note: LIGHT, HEAVY, CONDENSED not supported in BeOS R5 #ifdef __HAIKU__ - if(weight >= 0 && weight < 150) face |= B_LIGHT_FACE; - else if(weight >= 150 && weight < 250) face |= B_LIGHT_FACE; - else if(weight >= 250 && weight < 350) face |= B_LIGHT_FACE; - //else if(weight >= 350 && weight < 450) face |= B_REGULAR_FACE; - //else if(weight >= 450 && weight < 550) face |= B_REGULAR_FACE; - else if(weight >= 550 && weight < 650) face |= B_CONDENSED_FACE; + if (weight >= 0 && weight < 150) + face |= B_LIGHT_FACE; + else if (weight >= 150 && weight < 250) + face |= B_LIGHT_FACE; + else if (weight >= 250 && weight < 350) + face |= B_LIGHT_FACE; + // else if(weight >= 350 && weight < 450) face |= B_REGULAR_FACE; + // else if(weight >= 450 && weight < 550) face |= B_REGULAR_FACE; + else if (weight >= 550 && weight < 650) + face |= B_CONDENSED_FACE; #else - else if(weight >= 550 && weight < 650) face |= B_BOLD_FACE; + else if (weight >= 550 && weight < 650) + face |= B_BOLD_FACE; #endif - else if(weight >= 650 && weight < 750) face |= B_BOLD_FACE; + else if (weight >= 650 && weight < 750) + face |= B_BOLD_FACE; #ifndef __HAIKU__ - else if(weight >= 750 && weight < 850) face |= B_BOLD_FACE; - else if(weight >= 950) face |= B_BOLD_FACE; + else if (weight >= 750 && weight < 850) + face |= B_BOLD_FACE; + else if (weight >= 950) + face |= B_BOLD_FACE; #else - else if(weight >= 750 && weight < 850) face |= B_HEAVY_FACE; - else if(weight >= 950) face |= B_HEAVY_FACE; + else if (weight >= 750 && weight < 850) + face |= B_HEAVY_FACE; + else if (weight >= 950) + face |= B_HEAVY_FACE; #endif - BFont* tempFont = new BFont(); - bool found = false; - for(litehtml::string_vector::iterator i = fonts.begin(); - i != fonts.end(); i++) - { - if (B_OK == tempFont->SetFamilyAndFace(i->c_str(),face)) - { - found = true; - break; - } - } - - if (!found) - { - // default to the Be plain font - tempFont = new BFont(be_plain_font); - if (weight >= 550) - { - tempFont = new BFont(be_bold_font); - } - tempFont->SetFace(face); // chooses closest - } - - tempFont->SetSize(size); - - font_height hgt; - tempFont->GetHeight(&hgt); - fm->ascent = hgt.ascent; - fm->descent = hgt.descent; - fm->height = (int) (hgt.ascent + hgt.descent); - fm->x_height = (int) hgt.leading; - - return (litehtml::uint_ptr) tempFont; + BFont* tempFont = new BFont(); + bool found = false; + for (litehtml::string_vector::iterator i = fonts.begin(); i != fonts.end(); i++) { + if (B_OK == tempFont->SetFamilyAndFace(i->c_str(), face)) { + found = true; + break; + } + } + + if (!found) { + // default to the Be plain font + tempFont = new BFont(be_plain_font); + if (weight >= 550) { + tempFont = new BFont(be_bold_font); + } + tempFont->SetFace(face); // chooses closest + } + + tempFont->SetSize(size); + + font_height hgt; + tempFont->GetHeight(&hgt); + fm->ascent = hgt.ascent; + fm->descent = hgt.descent; + fm->height = (int)(hgt.ascent + hgt.descent); + fm->x_height = (int)hgt.leading; + + return (litehtml::uint_ptr)tempFont; } -void -LiteHtmlView::delete_font( litehtml::uint_ptr hFont ) -{ - std::cout << "delete_font" << std::endl; +void LiteHtmlView::delete_font(litehtml::uint_ptr hFont) { std::cout << "delete_font" << std::endl; } + +int LiteHtmlView::text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) { + // std::cout << "text_width" << std::endl; + BFont* fnt = (BFont*)hFont; + int width = fnt->StringWidth(text); + // std::cout << " Width: " << +width << std::endl; + return width; } -int -LiteHtmlView::text_width( const litehtml::tchar_t* text, - litehtml::uint_ptr hFont ) -{ - //std::cout << "text_width" << std::endl; - BFont* fnt = (BFont*)hFont; - int width = fnt->StringWidth(text); - //std::cout << " Width: " << +width << std::endl; - return width; +void LiteHtmlView::draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) { + // std::cout << "draw_text" << std::endl; + if (!text) return; + if (0 == strlen(text)) return; + BFont* fnt = (BFont*)hFont; + + // std::cout << " left: " << +pos.left() << ", top: " << +pos.top() << std::endl; + // std::cout << " RGBA: " << +color.red << "," << +color.green << "," << +color.blue << "," << +color.alpha << std::endl; + // std::cout << " Font size: " << +fnt->Size() << std::endl; + // std::cout << " Text: " << text << std::endl; + BRect bounds(Bounds()); + + // FillRect(bounds,B_SOLID_LOW); + + BPoint leftTop = bounds.LeftTop(); + // std::cout << " Bounds left: " << +leftTop.x << ", top: " << +leftTop.y << ", Width: " << +bounds.Width() << ", Height: " << +bounds.Height() << std::endl; + + font_height fh; + fnt->GetHeight(&fh); + int baseline = fh.ascent + fh.descent; // + 10; + int leftbase = 0; // 10; + MovePenTo(pos.left() + leftbase, pos.top() + baseline); // leftTop.x,leftTop.y); + SetFont(fnt); + // SetFont(be_plain_font); + rgb_color clr = ui_color(B_DOCUMENT_TEXT_COLOR); + /* + rgb_color clr; + clr.blue = 40; + clr.red = 40; + clr.green = 40; + */ + + clr.red = color.red; + clr.green = color.green; + clr.blue = color.blue; + clr.alpha = color.alpha; + + // std::cout << " Final RGBA: " << +clr.red << "," << +clr.green << "," << +clr.blue << "," << +clr.alpha << std::endl; + SetHighColor(clr); + SetLowColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + BString mystr(""); + // mystr << "text: "; + mystr << text; + DrawString(mystr); } -void -LiteHtmlView::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, - litehtml::uint_ptr hFont, litehtml::web_color color, - const litehtml::position& pos ) -{ - //std::cout << "draw_text" << std::endl; - if (!text) return; - if (0 == strlen(text)) return; - BFont* fnt = (BFont*)hFont; - - //std::cout << " left: " << +pos.left() << ", top: " << +pos.top() << std::endl; - //std::cout << " RGBA: " << +color.red << "," << +color.green << "," << +color.blue << "," << +color.alpha << std::endl; - //std::cout << " Font size: " << +fnt->Size() << std::endl; - //std::cout << " Text: " << text << std::endl; - BRect bounds(Bounds()); - - //FillRect(bounds,B_SOLID_LOW); - - BPoint leftTop = bounds.LeftTop(); - //std::cout << " Bounds left: " << +leftTop.x << ", top: " << +leftTop.y << ", Width: " << +bounds.Width() << ", Height: " << +bounds.Height() << std::endl; - - font_height fh; - fnt->GetHeight(&fh); - int baseline = fh.ascent + fh.descent;// + 10; - int leftbase = 0; //10; - MovePenTo(pos.left() + leftbase,pos.top() + baseline);//leftTop.x,leftTop.y); - SetFont(fnt); - //SetFont(be_plain_font); - rgb_color clr = ui_color(B_DOCUMENT_TEXT_COLOR); - /* - rgb_color clr; - clr.blue = 40; - clr.red = 40; - clr.green = 40; - */ - - clr.red = color.red; - clr.green = color.green; - clr.blue = color.blue; - clr.alpha = color.alpha; - - //std::cout << " Final RGBA: " << +clr.red << "," << +clr.green << "," << +clr.blue << "," << +clr.alpha << std::endl; - SetHighColor(clr); - SetLowColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); - BString mystr(""); - //mystr << "text: "; - mystr << text; - DrawString(mystr); +int LiteHtmlView::pt_to_px(int pt) { + std::cout << "pt_to_px" << std::endl; + return (int)((double)pt * 1.3333333333); } -int -LiteHtmlView::pt_to_px( int pt ) -{ - std::cout << "pt_to_px" << std::endl; - return (int) ((double) pt * 1.3333333333); +int LiteHtmlView::get_default_font_size() const { + // std::cout << "get_default_font_size" << std::endl; + return 12; } -int -LiteHtmlView::get_default_font_size() const -{ - //std::cout << "get_default_font_size" << std::endl; - return 12; +const litehtml::tchar_t* LiteHtmlView::get_default_font_name() const { + // std::cout << "get_default_font_name" << std::endl; + font_family fam; + font_style style; + be_plain_font->GetFamilyAndStyle(&fam, &style); + char* cp = strdup(fam); + return (litehtml::tchar_t*)cp; } -const litehtml::tchar_t* -LiteHtmlView::get_default_font_name() const -{ - //std::cout << "get_default_font_name" << std::endl; - font_family fam; - font_style style; - be_plain_font->GetFamilyAndStyle(&fam,&style); - char* cp = strdup(fam); - return (litehtml::tchar_t*)cp; +void LiteHtmlView::draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) { + std::cout << "draw_list_marker" << std::endl; + if (!marker.image.empty()) { + std::cout << " image marker" << std::endl; + } } -void -LiteHtmlView::draw_list_marker( litehtml::uint_ptr hdc, - const litehtml::list_marker& marker ) -{ - std::cout << "draw_list_marker" << std::endl; - if (!marker.image.empty()) - { - std::cout << " image marker" << std::endl; - } +void LiteHtmlView::load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) { + std::cout << "load_image" << std::endl; + + std::string url; + make_url(src, baseurl, url); + if (m_images.find(url.c_str()) == m_images.end()) { + BEntry entry(url.c_str(), true); + if (entry.Exists()) { + std::cout << " Loading bitmap from file" << std::endl; + BBitmap* img = BTranslationUtils::GetBitmap(url.c_str()); + m_images[url] = img; + } + } } -void -LiteHtmlView::load_image( const litehtml::tchar_t* src, - const litehtml::tchar_t* baseurl, bool redraw_on_ready ) -{ - std::cout << "load_image" << std::endl; - - std::string url; - make_url(src, baseurl, url); - if(m_images.find(url.c_str()) == m_images.end()) - { - BEntry entry(url.c_str(), true); - if (entry.Exists()) { - std::cout << " Loading bitmap from file" << std::endl; - BBitmap* img = BTranslationUtils::GetBitmap(url.c_str()); - m_images[url] = img; - } - } +void LiteHtmlView::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out) { + std::cout << "make_url" << std::endl; + std::cout << " url: " << url << std::endl; + if (!basepath || (basepath && !basepath[0])) { + if (!m_base_url.empty()) { + // out = urljoin(m_base_url, std::string(url)); + std::string ns(m_base_url); + ns += "/"; + ns += url; + out = ns; + } else { + out = url; + } + } else { + std::cout << " basepath: " << basepath << std::endl; + // out = urljoin(std::string(basepath), std::string(url)); + std::string ns(basepath); + ns += "/"; + ns += url; + out = ns; + } + std::cout << " Output url: " << out << std::endl; } -void -LiteHtmlView::make_url(const litehtml::tchar_t* url, - const litehtml::tchar_t* basepath, litehtml::tstring& out) -{ - std::cout << "make_url" << std::endl; - std::cout << " url: " << url << std::endl; - if(!basepath || (basepath && !basepath[0])) - { - if(!m_base_url.empty()) - { - //out = urljoin(m_base_url, std::string(url)); - std::string ns(m_base_url); - ns += "/"; - ns += url; - out = ns; - } else - { - out = url; - } - } else - { - std::cout << " basepath: " << basepath << std::endl; - //out = urljoin(std::string(basepath), std::string(url)); - std::string ns(basepath); - ns += "/"; - ns += url; - out = ns; - } - std::cout << " Output url: " << out << std::endl; +void LiteHtmlView::set_base_url(const litehtml::tchar_t* base_url) { + std::cout << "set_base_url" << std::endl; + /* + if(base_url) + { + m_base_url = urljoin(m_url, std::string(base_url)); + } else + { + */ + m_base_url = base_url; + std::cout << " base url set to: " << m_base_url << std::endl; + //} } -void -LiteHtmlView::set_base_url(const litehtml::tchar_t* base_url) -{ - std::cout << "set_base_url" << std::endl; -/* - if(base_url) - { - m_base_url = urljoin(m_url, std::string(base_url)); - } else - { - */ - m_base_url = base_url; - std::cout << " base url set to: " << m_base_url << std::endl; - //} +void LiteHtmlView::get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) { + std::cout << "get_image_size" << std::endl; + std::string url; + make_url(src, NULL, url); + const auto& miter(m_images.find(url.c_str())); + if (m_images.end() != miter) { + BBitmap* img = (BBitmap*)miter->second; + BRect size = img->Bounds(); + sz.width = size.Width(); + sz.height = size.Height(); + std::cout << " width: " << +sz.width << ", height: " << +sz.height << std::endl; + } } - -void -LiteHtmlView::get_image_size( const litehtml::tchar_t* src, - const litehtml::tchar_t* baseurl, litehtml::size& sz ) -{ - std::cout << "get_image_size" << std::endl; - std::string url; - make_url(src,NULL,url); - const auto& miter(m_images.find(url.c_str())); - if (m_images.end() != miter) - { - BBitmap* img = (BBitmap*)miter->second; - BRect size = img->Bounds(); - sz.width = size.Width(); - sz.height = size.Height(); - std::cout << " width: " << +sz.width << ", height: " << +sz.height << std::endl; - } +void LiteHtmlView::draw_image(litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos) { + std::string url; + make_url(src, baseurl, url); + const auto& img = m_images.find(url.c_str()); + if (img != m_images.end()) { + if (img->second) { + DrawBitmap(img->second, BPoint(pos.x, pos.y)); // TODO support scaling + // draw_txdib(cr, img->second.get(), pos.x, pos.y, pos.width, pos.height); + } + } } -void -LiteHtmlView::draw_image( litehtml::uint_ptr hdc, const litehtml::tchar_t* src, - const litehtml::tchar_t* baseurl, const litehtml::position& pos ) -{ - std::string url; - make_url(src, baseurl, url); - const auto& img = m_images.find(url.c_str()); - if(img != m_images.end()) - { - if(img->second) - { - DrawBitmap(img->second,BPoint(pos.x,pos.y)); // TODO support scaling - //draw_txdib(cr, img->second.get(), pos.x, pos.y, pos.width, pos.height); - } - } +void LiteHtmlView::draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) { + std::cout << "draw_background" << std::endl; + if (0 < bg.image.length()) { + std::cout << " background includes an image!" << std::endl; + draw_image(hdc, bg.image.c_str(), m_base_url.c_str(), litehtml::position(bg.position_x, bg.position_y, bg.image_size.width, bg.image_size.height)); + } } -void -LiteHtmlView::draw_background( litehtml::uint_ptr hdc, - const litehtml::background_paint& bg ) -{ - std::cout << "draw_background" << std::endl; - if (0 < bg.image.length()) - { - std::cout << " background includes an image!" << std::endl; - draw_image(hdc,bg.image.c_str(),m_base_url.c_str(),litehtml::position(bg.position_x,bg.position_y,bg.image_size.width,bg.image_size.height)); - } +void LiteHtmlView::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) { + std::cout << "draw_borders" << std::endl; + int bdr_top = 0; + int bdr_bottom = 0; + int bdr_left = 0; + int bdr_right = 0; + + // std::cout << " uint ptr: " << +hdc << std::endl; + // std::cout << " this ptr: " << +this << std::endl; + + if (borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) { + bdr_top = (int)borders.top.width; + std::cout << " Border top: " << bdr_right << std::endl; + } + if (borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) { + bdr_bottom = (int)borders.bottom.width; + std::cout << " Border bottom: " << bdr_right << std::endl; + } + if (borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) { + bdr_left = (int)borders.left.width; + std::cout << " Border left: " << bdr_right << std::endl; + } + if (borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) { + bdr_right = (int)borders.right.width; + std::cout << " Border right: " << bdr_right << std::endl; + } + + if (bdr_bottom) { + // draw rectangle for now - no check for radius + StrokeRect(BRect(BPoint(draw_pos.left(), draw_pos.bottom()), BPoint(draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom))); + } } -void -LiteHtmlView::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) -{ - std::cout << "draw_borders" << std::endl; - int bdr_top = 0; - int bdr_bottom = 0; - int bdr_left = 0; - int bdr_right = 0; - - //std::cout << " uint ptr: " << +hdc << std::endl; - //std::cout << " this ptr: " << +this << std::endl; +void LiteHtmlView::transform_text(litehtml::tstring& text, litehtml::text_transform tt) { std::cout << "transform_text" << std::endl; } - if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) - { - bdr_top = (int) borders.top.width; - std::cout << " Border top: " << bdr_right << std::endl; - } - if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) - { - bdr_bottom = (int) borders.bottom.width; - std::cout << " Border bottom: " << bdr_right << std::endl; - } - if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) - { - bdr_left = (int) borders.left.width; - std::cout << " Border left: " << bdr_right << std::endl; - } - if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) - { - bdr_right = (int) borders.right.width; - std::cout << " Border right: " << bdr_right << std::endl; - } - - - if (bdr_bottom) - { - // draw rectangle for now - no check for radius - StrokeRect( - BRect( - BPoint(draw_pos.left(), draw_pos.bottom()), - BPoint(draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom) - ) - ); - } +void LiteHtmlView::set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) { std::cout << "set_clip" << std::endl; } + +void LiteHtmlView::del_clip() { std::cout << "del_clip" << std::endl; } + +std::shared_ptr LiteHtmlView::create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) { + // std::cout << "create_element" << std::endl; + return 0; } -void -LiteHtmlView::transform_text(litehtml::tstring& text, litehtml::text_transform tt) -{ - std::cout << "transform_text" << std::endl; +void LiteHtmlView::get_media_features(litehtml::media_features& media) const { + std::cout << "get_media_features" << std::endl; + litehtml::position client; + get_client_rect(client); + media.type = litehtml::media_type_screen; + media.width = client.width; + media.height = client.height; + BRect bounds(Bounds()); + media.device_width = bounds.Width(); + media.device_height = bounds.Height(); + media.color = 8; + media.monochrome = 0; + media.color_index = 256; + media.resolution = 96; } -void -LiteHtmlView::set_clip( const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y ) -{ - std::cout << "set_clip" << std::endl; +void LiteHtmlView::link(const std::shared_ptr& ptr, const litehtml::element::ptr& el) { std::cout << "link" << std::endl; } + +void LiteHtmlView::set_caption(const char* caption) { std::cout << "set_caption" << std::endl; } + +void LiteHtmlView::get_client_rect(litehtml::position& client) const { + // std::cout << "get_client_rect" << std::endl; + BRect bounds(Bounds()); + BPoint leftTop = bounds.LeftTop(); + client.width = bounds.Width(); + client.height = bounds.Height(); + client.x = leftTop.x; + client.y = leftTop.y; } -void -LiteHtmlView::del_clip() -{ - std::cout << "del_clip" << std::endl; -} +void LiteHtmlView::on_anchor_click(const char* base, const litehtml::element::ptr& anchor) { std::cout << "on_anchor_click" << std::endl; } +void LiteHtmlView::set_cursor(const char* cursor) { std::cout << "set_cursor" << std::endl; } +void LiteHtmlView::import_css(litehtml::tstring& s1, const litehtml::tstring& s2, litehtml::tstring& s3) { std::cout << "import_css" << std::endl; } -std::shared_ptr -LiteHtmlView::create_element(const litehtml::tchar_t *tag_name, - const litehtml::string_map &attributes, - const std::shared_ptr &doc) -{ - //std::cout << "create_element" << std::endl; - return 0; -} - -void -LiteHtmlView::get_media_features(litehtml::media_features& media) const -{ - std::cout << "get_media_features" << std::endl; - litehtml::position client; - get_client_rect(client); - media.type = litehtml::media_type_screen; - media.width = client.width; - media.height = client.height; - BRect bounds(Bounds()); - media.device_width = bounds.Width(); - media.device_height = bounds.Height(); - media.color = 8; - media.monochrome = 0; - media.color_index = 256; - media.resolution = 96; -} - -void -LiteHtmlView::link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) -{ - std::cout << "link" << std::endl; -} - -void -LiteHtmlView::set_caption(const char* caption) -{ - std::cout << "set_caption" << std::endl; -} - -void -LiteHtmlView::get_client_rect(litehtml::position& client) const -{ - //std::cout << "get_client_rect" << std::endl; - BRect bounds(Bounds()); - BPoint leftTop = bounds.LeftTop(); - client.width = bounds.Width(); - client.height = bounds.Height(); - client.x = leftTop.x; - client.y = leftTop.y; -} - -void -LiteHtmlView::on_anchor_click(const char* base, const litehtml::element::ptr& anchor) -{ - std::cout << "on_anchor_click" << std::endl; -} - -void -LiteHtmlView::set_cursor(const char* cursor) -{ - std::cout << "set_cursor" << std::endl; -} - -void -LiteHtmlView::import_css(litehtml::tstring& s1, const litehtml::tstring& s2, litehtml::tstring& s3) -{ - std::cout << "import_css" << std::endl; -} - -void -LiteHtmlView::get_language(litehtml::tstring& s1, litehtml::tstring& s2) const -{ - std::cout << "get_language" << std::endl; -} +void LiteHtmlView::get_language(litehtml::tstring& s1, litehtml::tstring& s2) const { std::cout << "get_language" << std::endl; } diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/haiku/container_haiku.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/haiku/container_haiku.h index 31d7f121f..878199979 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/haiku/container_haiku.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/haiku/container_haiku.h @@ -7,81 +7,73 @@ #ifndef LITEHTMLVIEW_H #define LITEHTMLVIEW_H -#include "../../include/litehtml.h" +#include #include #include -#include +#include "../../include/litehtml.h" class BBitmap; +enum { M_HTML_RENDERED = 'hrnd' }; -enum { - M_HTML_RENDERED = 'hrnd' -}; +class LiteHtmlView : public BView, public litehtml::document_container { + public: + // LiteHtmlView(BMessage *archive); + LiteHtmlView(BRect frame, const char* name); + // LiteHtmlView(const char *name, uint32 flags, BLayout *layout=NULL); -class LiteHtmlView : public BView, public litehtml::document_container -{ -public: - //LiteHtmlView(BMessage *archive); - LiteHtmlView(BRect frame, const char *name); - //LiteHtmlView(const char *name, uint32 flags, BLayout *layout=NULL); - - virtual ~LiteHtmlView(); - - void SetContext(litehtml::context* ctx); - void RenderFile(const char* localFilePath); - void RenderHTML(const std::string& htmlText); - - - virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; - virtual void delete_font(litehtml::uint_ptr hFont) override; - virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; - virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; - virtual int pt_to_px(int pt) override; - virtual int get_default_font_size() const override; - virtual const litehtml::tchar_t* get_default_font_name() const override; - virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; - virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; - virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; - virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; - virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; - virtual std::shared_ptr create_element(const litehtml::tchar_t *tag_name, - const litehtml::string_map &attributes, - const std::shared_ptr &doc) override; - virtual void get_media_features(litehtml::media_features& media) const override; - //virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; - virtual void link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) override; + virtual ~LiteHtmlView(); + void SetContext(litehtml::context* ctx); + void RenderFile(const char* localFilePath); + void RenderHTML(const std::string& htmlText); - virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; - virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; - virtual void del_clip() override; - - // unimplemented - virtual void set_caption(const char*); - virtual void get_client_rect(litehtml::position& client) const; - virtual void set_base_url(const char*); - virtual void on_anchor_click(const char*, const litehtml::element::ptr&); - virtual void set_cursor(const char*); - virtual void import_css(litehtml::tstring&, const litehtml::tstring&, litehtml::tstring&); - virtual void get_language(litehtml::tstring&, litehtml::tstring&) const; - - //BView - virtual void Draw(BRect updateRect) override; - virtual void GetPreferredSize(float* width, float* height) override; - -protected: - void make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out); - virtual void draw_image( litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos ); - -private: - litehtml::context* fContext; - litehtml::document::ptr m_html; - std::map m_images; - litehtml::tstring m_base_url; - litehtml::tstring m_url; + virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; + virtual void delete_font(litehtml::uint_ptr hFont) override; + virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; + virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; + virtual int pt_to_px(int pt) override; + virtual int get_default_font_size() const override; + virtual const litehtml::tchar_t* get_default_font_name() const override; + virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; + virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; + virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; + virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; + virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; + virtual std::shared_ptr create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) override; + virtual void get_media_features(litehtml::media_features& media) const override; + // virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; + virtual void link(const std::shared_ptr& ptr, const litehtml::element::ptr& el) override; + + virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; + virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; + virtual void del_clip() override; + + // unimplemented + virtual void set_caption(const char*); + virtual void get_client_rect(litehtml::position& client) const; + virtual void set_base_url(const char*); + virtual void on_anchor_click(const char*, const litehtml::element::ptr&); + virtual void set_cursor(const char*); + virtual void import_css(litehtml::tstring&, const litehtml::tstring&, litehtml::tstring&); + virtual void get_language(litehtml::tstring&, litehtml::tstring&) const; + + // BView + virtual void Draw(BRect updateRect) override; + virtual void GetPreferredSize(float* width, float* height) override; + + protected: + void make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out); + virtual void draw_image(litehtml::uint_ptr hdc, const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, const litehtml::position& pos); + + private: + litehtml::context* fContext; + litehtml::document::ptr m_html; + std::map m_images; + litehtml::tstring m_base_url; + litehtml::tstring m_url; }; #endif diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/linux/container_linux.cpp b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/linux/container_linux.cpp index c52e11865..9e3539d11 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/linux/container_linux.cpp +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/linux/container_linux.cpp @@ -1,895 +1,695 @@ #include "container_linux.h" + #include #ifndef M_PI -# define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif -container_linux::container_linux() -{ - m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2); - m_temp_cr = cairo_create(m_temp_surface); +container_linux::container_linux() { + m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2); + m_temp_cr = cairo_create(m_temp_surface); } -container_linux::~container_linux() -{ - clear_images(); - cairo_surface_destroy(m_temp_surface); - cairo_destroy(m_temp_cr); +container_linux::~container_linux() { + clear_images(); + cairo_surface_destroy(m_temp_surface); + cairo_destroy(m_temp_cr); } -litehtml::uint_ptr container_linux::create_font( const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm ) -{ - PangoFontDescription *desc = pango_font_description_from_string (faceName); - pango_font_description_set_absolute_size(desc, size * PANGO_SCALE); - if(italic == litehtml::fontStyleItalic ) - { - pango_font_description_set_style(desc, PANGO_STYLE_ITALIC); - } else - { - pango_font_description_set_style(desc, PANGO_STYLE_NORMAL); - } - PangoWeight fnt_weight; - if(weight >= 0 && weight < 150) fnt_weight = PANGO_WEIGHT_THIN; - else if(weight >= 150 && weight < 250) fnt_weight = PANGO_WEIGHT_ULTRALIGHT; - else if(weight >= 250 && weight < 350) fnt_weight = PANGO_WEIGHT_LIGHT; - else if(weight >= 350 && weight < 450) fnt_weight = PANGO_WEIGHT_NORMAL; - else if(weight >= 450 && weight < 550) fnt_weight = PANGO_WEIGHT_MEDIUM; - else if(weight >= 550 && weight < 650) fnt_weight = PANGO_WEIGHT_SEMIBOLD; - else if(weight >= 650 && weight < 750) fnt_weight = PANGO_WEIGHT_BOLD; - else if(weight >= 750 && weight < 850) fnt_weight = PANGO_WEIGHT_ULTRABOLD; - else fnt_weight = PANGO_WEIGHT_HEAVY; +litehtml::uint_ptr container_linux::create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) { + PangoFontDescription* desc = pango_font_description_from_string(faceName); + pango_font_description_set_absolute_size(desc, size * PANGO_SCALE); + if (italic == litehtml::fontStyleItalic) { + pango_font_description_set_style(desc, PANGO_STYLE_ITALIC); + } else { + pango_font_description_set_style(desc, PANGO_STYLE_NORMAL); + } + PangoWeight fnt_weight; + if (weight >= 0 && weight < 150) + fnt_weight = PANGO_WEIGHT_THIN; + else if (weight >= 150 && weight < 250) + fnt_weight = PANGO_WEIGHT_ULTRALIGHT; + else if (weight >= 250 && weight < 350) + fnt_weight = PANGO_WEIGHT_LIGHT; + else if (weight >= 350 && weight < 450) + fnt_weight = PANGO_WEIGHT_NORMAL; + else if (weight >= 450 && weight < 550) + fnt_weight = PANGO_WEIGHT_MEDIUM; + else if (weight >= 550 && weight < 650) + fnt_weight = PANGO_WEIGHT_SEMIBOLD; + else if (weight >= 650 && weight < 750) + fnt_weight = PANGO_WEIGHT_BOLD; + else if (weight >= 750 && weight < 850) + fnt_weight = PANGO_WEIGHT_ULTRABOLD; + else + fnt_weight = PANGO_WEIGHT_HEAVY; - pango_font_description_set_weight(desc, fnt_weight); + pango_font_description_set_weight(desc, fnt_weight); - cairo_font* ret = nullptr; + cairo_font* ret = nullptr; - if(fm) - { - cairo_save(m_temp_cr); - PangoLayout *layout = pango_cairo_create_layout(m_temp_cr); - PangoContext *context = pango_layout_get_context(layout); - PangoLanguage *language = pango_language_get_default(); - pango_layout_set_font_description(layout, desc); - PangoFontMetrics *metrics = pango_context_get_metrics(context, desc, language); + if (fm) { + cairo_save(m_temp_cr); + PangoLayout* layout = pango_cairo_create_layout(m_temp_cr); + PangoContext* context = pango_layout_get_context(layout); + PangoLanguage* language = pango_language_get_default(); + pango_layout_set_font_description(layout, desc); + PangoFontMetrics* metrics = pango_context_get_metrics(context, desc, language); - fm->ascent = PANGO_PIXELS((double)pango_font_metrics_get_ascent(metrics)); - fm->descent = PANGO_PIXELS((double)pango_font_metrics_get_descent(metrics)); - fm->height = fm->ascent + fm->descent; - fm->x_height = fm->height; + fm->ascent = PANGO_PIXELS((double)pango_font_metrics_get_ascent(metrics)); + fm->descent = PANGO_PIXELS((double)pango_font_metrics_get_descent(metrics)); + fm->height = fm->ascent + fm->descent; + fm->x_height = fm->height; - pango_layout_set_text(layout, "x", 1); - - int x_width, x_height; - pango_layout_get_pixel_size(layout, &x_width, &x_height); - - fm->x_height = x_height; - - cairo_restore(m_temp_cr); - - g_object_unref(layout); - pango_font_metrics_unref(metrics); - - ret = new cairo_font; - ret->font = desc; - ret->size = size; - ret->strikeout = (decoration & litehtml::font_decoration_linethrough) != 0; - ret->underline = (decoration & litehtml::font_decoration_underline) != 0; - ret->ascent = fm->ascent; - ret->descent = fm->descent; - - ret->underline_thickness = pango_font_metrics_get_underline_thickness(metrics); - ret->underline_position = -pango_font_metrics_get_underline_position(metrics); - pango_quantize_line_geometry(&ret->underline_thickness, &ret->underline_position); - ret->underline_thickness = PANGO_PIXELS(ret->underline_thickness); - ret->underline_position = -1;//PANGO_PIXELS(ret->underline_position); - - ret->strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness(metrics); - ret->strikethrough_position = pango_font_metrics_get_strikethrough_position(metrics); - pango_quantize_line_geometry(&ret->strikethrough_thickness, &ret->strikethrough_position); - ret->strikethrough_thickness = PANGO_PIXELS(ret->strikethrough_thickness); - ret->strikethrough_position = PANGO_PIXELS(ret->strikethrough_position); - } - - return (litehtml::uint_ptr) ret; -} - -void container_linux::delete_font( litehtml::uint_ptr hFont ) -{ - auto* fnt = (cairo_font*) hFont; - if(fnt) - { - pango_font_description_free(fnt->font); - delete fnt; - } -} - -int container_linux::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont ) -{ - auto* fnt = (cairo_font*) hFont; - - cairo_save(m_temp_cr); - - PangoLayout *layout = pango_cairo_create_layout(m_temp_cr); - pango_layout_set_font_description(layout, fnt->font); - - pango_layout_set_text(layout, text, -1); - pango_cairo_update_layout (m_temp_cr, layout); + pango_layout_set_text(layout, "x", 1); int x_width, x_height; pango_layout_get_pixel_size(layout, &x_width, &x_height); - cairo_restore(m_temp_cr); + fm->x_height = x_height; - return (int) x_width; -} - -void container_linux::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos ) -{ - auto* fnt = (cairo_font*) hFont; - auto* cr = (cairo_t*) hdc; - cairo_save(cr); - - apply_clip(cr); - - set_color(cr, color); - - PangoLayout *layout = pango_cairo_create_layout(cr); - pango_layout_set_font_description (layout, fnt->font); - pango_layout_set_text (layout, text, -1); - - int baseline = PANGO_PIXELS(pango_layout_get_baseline(layout)); - - PangoRectangle ink_rect, logical_rect; - pango_layout_get_pixel_extents(layout, &ink_rect, &logical_rect); - - int text_baseline = pos.height - fnt->descent; - - int x = pos.left() + logical_rect.x; - int y = pos.top() + logical_rect.y + text_baseline - baseline; - - cairo_move_to(cr, x, y); - pango_cairo_update_layout (cr, layout); - pango_cairo_show_layout (cr, layout); - - int tw = 0; - - if(fnt->underline || fnt->strikeout) - { - tw = text_width(text, hFont); - } - - if(fnt->underline) - { - cairo_set_line_width(cr, fnt->underline_thickness); - cairo_move_to(cr, x, pos.top() + text_baseline - fnt->underline_position + 0.5); - cairo_line_to(cr, x + tw, pos.top() + text_baseline - fnt->underline_position + 0.5); - cairo_stroke(cr); - } - if(fnt->strikeout) - { - cairo_set_line_width(cr, fnt->strikethrough_thickness); - cairo_move_to(cr, x, pos.top() + text_baseline - fnt->strikethrough_position - 0.5); - cairo_line_to(cr, x + tw, pos.top() + text_baseline - fnt->strikethrough_position - 0.5); - cairo_stroke(cr); - } - - cairo_restore(cr); + cairo_restore(m_temp_cr); g_object_unref(layout); + pango_font_metrics_unref(metrics); + + ret = new cairo_font; + ret->font = desc; + ret->size = size; + ret->strikeout = (decoration & litehtml::font_decoration_linethrough) != 0; + ret->underline = (decoration & litehtml::font_decoration_underline) != 0; + ret->ascent = fm->ascent; + ret->descent = fm->descent; + + ret->underline_thickness = pango_font_metrics_get_underline_thickness(metrics); + ret->underline_position = -pango_font_metrics_get_underline_position(metrics); + pango_quantize_line_geometry(&ret->underline_thickness, &ret->underline_position); + ret->underline_thickness = PANGO_PIXELS(ret->underline_thickness); + ret->underline_position = -1; // PANGO_PIXELS(ret->underline_position); + + ret->strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness(metrics); + ret->strikethrough_position = pango_font_metrics_get_strikethrough_position(metrics); + pango_quantize_line_geometry(&ret->strikethrough_thickness, &ret->strikethrough_position); + ret->strikethrough_thickness = PANGO_PIXELS(ret->strikethrough_thickness); + ret->strikethrough_position = PANGO_PIXELS(ret->strikethrough_position); + } + + return (litehtml::uint_ptr)ret; } -int container_linux::pt_to_px( int pt ) const -{ - GdkScreen* screen = gdk_screen_get_default(); - double dpi = gdk_screen_get_resolution(screen); - - return (int) ((double) pt * dpi / 72.0); +void container_linux::delete_font(litehtml::uint_ptr hFont) { + auto* fnt = (cairo_font*)hFont; + if (fnt) { + pango_font_description_free(fnt->font); + delete fnt; + } } -int container_linux::get_default_font_size() const -{ - return pt_to_px(12); +int container_linux::text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) { + auto* fnt = (cairo_font*)hFont; + + cairo_save(m_temp_cr); + + PangoLayout* layout = pango_cairo_create_layout(m_temp_cr); + pango_layout_set_font_description(layout, fnt->font); + + pango_layout_set_text(layout, text, -1); + pango_cairo_update_layout(m_temp_cr, layout); + + int x_width, x_height; + pango_layout_get_pixel_size(layout, &x_width, &x_height); + + cairo_restore(m_temp_cr); + + return (int)x_width; } -void container_linux::draw_list_marker( litehtml::uint_ptr hdc, const litehtml::list_marker& marker ) -{ - if(!marker.image.empty()) - { - /*litehtml::tstring url; - make_url(marker.image.c_str(), marker.baseurl, url); +void container_linux::draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) { + auto* fnt = (cairo_font*)hFont; + auto* cr = (cairo_t*)hdc; + cairo_save(cr); - lock_images_cache(); - images_map::iterator img_i = m_images.find(url.c_str()); - if(img_i != m_images.end()) - { - if(img_i->second) - { - draw_txdib((cairo_t*) hdc, img_i->second, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); - } - } - unlock_images_cache();*/ - } else - { - switch(marker.marker_type) - { - case litehtml::list_style_type_circle: - { - draw_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 1); - } - break; - case litehtml::list_style_type_disc: - { - fill_ellipse((cairo_t*) hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color); - } - break; - case litehtml::list_style_type_square: - if(hdc) - { - auto* cr = (cairo_t*) hdc; - cairo_save(cr); + apply_clip(cr); - cairo_new_path(cr); - cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); + set_color(cr, color); - set_color(cr, marker.color); - cairo_fill(cr); - cairo_restore(cr); - } - break; - default: - /*do nothing*/ - break; - } - } + PangoLayout* layout = pango_cairo_create_layout(cr); + pango_layout_set_font_description(layout, fnt->font); + pango_layout_set_text(layout, text, -1); + + int baseline = PANGO_PIXELS(pango_layout_get_baseline(layout)); + + PangoRectangle ink_rect, logical_rect; + pango_layout_get_pixel_extents(layout, &ink_rect, &logical_rect); + + int text_baseline = pos.height - fnt->descent; + + int x = pos.left() + logical_rect.x; + int y = pos.top() + logical_rect.y + text_baseline - baseline; + + cairo_move_to(cr, x, y); + pango_cairo_update_layout(cr, layout); + pango_cairo_show_layout(cr, layout); + + int tw = 0; + + if (fnt->underline || fnt->strikeout) { + tw = text_width(text, hFont); + } + + if (fnt->underline) { + cairo_set_line_width(cr, fnt->underline_thickness); + cairo_move_to(cr, x, pos.top() + text_baseline - fnt->underline_position + 0.5); + cairo_line_to(cr, x + tw, pos.top() + text_baseline - fnt->underline_position + 0.5); + cairo_stroke(cr); + } + if (fnt->strikeout) { + cairo_set_line_width(cr, fnt->strikethrough_thickness); + cairo_move_to(cr, x, pos.top() + text_baseline - fnt->strikethrough_position - 0.5); + cairo_line_to(cr, x + tw, pos.top() + text_baseline - fnt->strikethrough_position - 0.5); + cairo_stroke(cr); + } + + cairo_restore(cr); + + g_object_unref(layout); } -void container_linux::load_image( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready ) -{ - litehtml::tstring url; - make_url(src, baseurl, url); - if(m_images.find(url) == m_images.end()) - { - try - { - Glib::RefPtr img = get_image(url.c_str(), true); - if(img) - { - m_images[url.c_str()] = img; - } - } catch(...) - { - m_images[url.c_str()] = Glib::RefPtr(nullptr); - } - } +int container_linux::pt_to_px(int pt) const { + GdkScreen* screen = gdk_screen_get_default(); + double dpi = gdk_screen_get_resolution(screen); + + return (int)((double)pt * dpi / 72.0); } -void container_linux::get_image_size( const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz ) -{ - litehtml::tstring url; - make_url(src, baseurl, url); +int container_linux::get_default_font_size() const { return pt_to_px(12); } - auto img = m_images.find(url); - if(img != m_images.end()) - { - if(img->second) - { - sz.width = img->second->get_width(); - sz.height = img->second->get_height(); - } else - { - sz.width = 0; - sz.height = 0; +void container_linux::draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) { + if (!marker.image.empty()) { + /*litehtml::tstring url; + make_url(marker.image.c_str(), marker.baseurl, url); + + lock_images_cache(); + images_map::iterator img_i = m_images.find(url.c_str()); + if(img_i != m_images.end()) + { + if(img_i->second) + { + draw_txdib((cairo_t*) hdc, img_i->second, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); + } + } + unlock_images_cache();*/ + } else { + switch (marker.marker_type) { + case litehtml::list_style_type_circle: { + draw_ellipse((cairo_t*)hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color, 1); + } break; + case litehtml::list_style_type_disc: { + fill_ellipse((cairo_t*)hdc, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height, marker.color); + } break; + case litehtml::list_style_type_square: + if (hdc) { + auto* cr = (cairo_t*)hdc; + cairo_save(cr); + + cairo_new_path(cr); + cairo_rectangle(cr, marker.pos.x, marker.pos.y, marker.pos.width, marker.pos.height); + + set_color(cr, marker.color); + cairo_fill(cr); + cairo_restore(cr); } - } else - { - sz.width = 0; - sz.height = 0; - } + break; + default: + /*do nothing*/ + break; + } + } } -void container_linux::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg ) -{ - auto* cr = (cairo_t*) hdc; - cairo_save(cr); - apply_clip(cr); - - rounded_rectangle(cr, bg.border_box, bg.border_radius); - cairo_clip(cr); - - cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height); - cairo_clip(cr); - - if(bg.color.alpha) - { - set_color(cr, bg.color); - cairo_paint(cr); - } - - litehtml::tstring url; - make_url(bg.image.c_str(), bg.baseurl.c_str(), url); - - //lock_images_cache(); - auto img_i = m_images.find(url); - if(img_i != m_images.end() && img_i->second) - { - Glib::RefPtr bgbmp = img_i->second; - - Glib::RefPtr new_img; - if(bg.image_size.width != bgbmp->get_width() || bg.image_size.height != bgbmp->get_height()) - { - new_img = bgbmp->scale_simple(bg.image_size.width, bg.image_size.height, Gdk::INTERP_BILINEAR); - bgbmp = new_img; - } - - cairo_surface_t* img = surface_from_pixbuf(bgbmp); - cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img); - cairo_matrix_t flib_m; - cairo_matrix_init_identity(&flib_m); - cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y); - cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); - cairo_pattern_set_matrix (pattern, &flib_m); - - switch(bg.repeat) - { - case litehtml::background_repeat_no_repeat: - draw_pixbuf(cr, bgbmp, bg.position_x, bg.position_y, bgbmp->get_width(), bgbmp->get_height()); - break; - - case litehtml::background_repeat_repeat_x: - cairo_set_source(cr, pattern); - cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->get_height()); - cairo_fill(cr); - break; - - case litehtml::background_repeat_repeat_y: - cairo_set_source(cr, pattern); - cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->get_width(), bg.clip_box.height); - cairo_fill(cr); - break; - - case litehtml::background_repeat_repeat: - cairo_set_source(cr, pattern); - cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height); - cairo_fill(cr); - break; - } - - cairo_pattern_destroy(pattern); - cairo_surface_destroy(img); - - } -// unlock_images_cache(); - cairo_restore(cr); +void container_linux::load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) { + litehtml::tstring url; + make_url(src, baseurl, url); + if (m_images.find(url) == m_images.end()) { + try { + Glib::RefPtr img = get_image(url.c_str(), true); + if (img) { + m_images[url.c_str()] = img; + } + } catch (...) { + m_images[url.c_str()] = Glib::RefPtr(nullptr); + } + } } -void container_linux::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out) -{ - out = url; +void container_linux::get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) { + litehtml::tstring url; + make_url(src, baseurl, url); + + auto img = m_images.find(url); + if (img != m_images.end()) { + if (img->second) { + sz.width = img->second->get_width(); + sz.height = img->second->get_height(); + } else { + sz.width = 0; + sz.height = 0; + } + } else { + sz.width = 0; + sz.height = 0; + } } -void container_linux::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg) -{ - if(rx > 0 && ry > 0) - { +void container_linux::draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) { + auto* cr = (cairo_t*)hdc; + cairo_save(cr); + apply_clip(cr); - cairo_save(cr); + rounded_rectangle(cr, bg.border_box, bg.border_radius); + cairo_clip(cr); - cairo_translate(cr, x, y); - cairo_scale(cr, 1, ry / rx); - cairo_translate(cr, -x, -y); + cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height); + cairo_clip(cr); - if(neg) - { - cairo_arc_negative(cr, x, y, rx, a1, a2); - } else - { - cairo_arc(cr, x, y, rx, a1, a2); - } + if (bg.color.alpha) { + set_color(cr, bg.color); + cairo_paint(cr); + } - cairo_restore(cr); - } else - { - cairo_move_to(cr, x, y); - } + litehtml::tstring url; + make_url(bg.image.c_str(), bg.baseurl.c_str(), url); + + // lock_images_cache(); + auto img_i = m_images.find(url); + if (img_i != m_images.end() && img_i->second) { + Glib::RefPtr bgbmp = img_i->second; + + Glib::RefPtr new_img; + if (bg.image_size.width != bgbmp->get_width() || bg.image_size.height != bgbmp->get_height()) { + new_img = bgbmp->scale_simple(bg.image_size.width, bg.image_size.height, Gdk::INTERP_BILINEAR); + bgbmp = new_img; + } + + cairo_surface_t* img = surface_from_pixbuf(bgbmp); + cairo_pattern_t* pattern = cairo_pattern_create_for_surface(img); + cairo_matrix_t flib_m; + cairo_matrix_init_identity(&flib_m); + cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y); + cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); + cairo_pattern_set_matrix(pattern, &flib_m); + + switch (bg.repeat) { + case litehtml::background_repeat_no_repeat: + draw_pixbuf(cr, bgbmp, bg.position_x, bg.position_y, bgbmp->get_width(), bgbmp->get_height()); + break; + + case litehtml::background_repeat_repeat_x: + cairo_set_source(cr, pattern); + cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->get_height()); + cairo_fill(cr); + break; + + case litehtml::background_repeat_repeat_y: + cairo_set_source(cr, pattern); + cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->get_width(), bg.clip_box.height); + cairo_fill(cr); + break; + + case litehtml::background_repeat_repeat: + cairo_set_source(cr, pattern); + cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height); + cairo_fill(cr); + break; + } + + cairo_pattern_destroy(pattern); + cairo_surface_destroy(img); + } + // unlock_images_cache(); + cairo_restore(cr); } -void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) -{ - auto* cr = (cairo_t*) hdc; - cairo_save(cr); - apply_clip(cr); +void container_linux::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out) { out = url; } - cairo_new_path(cr); +void container_linux::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg) { + if (rx > 0 && ry > 0) { + cairo_save(cr); - int bdr_top = 0; - int bdr_bottom = 0; - int bdr_left = 0; - int bdr_right = 0; + cairo_translate(cr, x, y); + cairo_scale(cr, 1, ry / rx); + cairo_translate(cr, -x, -y); - if(borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) - { - bdr_top = (int) borders.top.width; - } - if(borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) - { - bdr_bottom = (int) borders.bottom.width; - } - if(borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) - { - bdr_left = (int) borders.left.width; - } - if(borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) - { - bdr_right = (int) borders.right.width; - } + if (neg) { + cairo_arc_negative(cr, x, y, rx, a1, a2); + } else { + cairo_arc(cr, x, y, rx, a1, a2); + } - // draw right border - if(bdr_right) - { - set_color(cr, borders.right.color); - - double r_top = borders.radius.top_right_x; - double r_bottom = borders.radius.bottom_right_x; - - if(r_top) - { - double end_angle = 2 * M_PI; - double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_top / (double) bdr_right + 1); - - add_path_arc(cr, - draw_pos.right() - r_top, - draw_pos.top() + r_top, - r_top - bdr_right, - r_top - bdr_right + (bdr_right - bdr_top), - end_angle, - start_angle, true); - - add_path_arc(cr, - draw_pos.right() - r_top, - draw_pos.top() + r_top, - r_top, - r_top, - start_angle, - end_angle, false); - } else - { - cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); - cairo_line_to(cr, draw_pos.right(), draw_pos.top()); - } - - if(r_bottom) - { - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom); - - double start_angle = 0; - double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_right + 1); - - add_path_arc(cr, - draw_pos.right() - r_bottom, - draw_pos.bottom() - r_bottom, - r_bottom, - r_bottom, - start_angle, - end_angle, false); - - add_path_arc(cr, - draw_pos.right() - r_bottom, - draw_pos.bottom() - r_bottom, - r_bottom - bdr_right, - r_bottom - bdr_right + (bdr_right - bdr_bottom), - end_angle, - start_angle, true); - } else - { - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); - } - - cairo_fill(cr); - } - - // draw bottom border - if(bdr_bottom) - { - set_color(cr, borders.bottom.color); - - double r_left = borders.radius.bottom_left_x; - double r_right = borders.radius.bottom_right_x; - - if(r_left) - { - double start_angle = M_PI / 2.0; - double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_left / (double) bdr_bottom + 1); - - add_path_arc(cr, - draw_pos.left() + r_left, - draw_pos.bottom() - r_left, - r_left - bdr_bottom + (bdr_bottom - bdr_left), - r_left - bdr_bottom, - start_angle, - end_angle, false); - - add_path_arc(cr, - draw_pos.left() + r_left, - draw_pos.bottom() - r_left, - r_left, - r_left, - end_angle, - start_angle, true); - } else - { - cairo_move_to(cr, draw_pos.left(), draw_pos.bottom()); - cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); - } - - if(r_right) - { - cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom()); - - double end_angle = M_PI / 2.0; - double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_right / (double) bdr_bottom + 1); - - add_path_arc(cr, - draw_pos.right() - r_right, - draw_pos.bottom() - r_right, - r_right, - r_right, - end_angle, - start_angle, true); - - add_path_arc(cr, - draw_pos.right() - r_right, - draw_pos.bottom() - r_right, - r_right - bdr_bottom + (bdr_bottom - bdr_right), - r_right - bdr_bottom, - start_angle, - end_angle, false); - } else - { - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); - cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); - } - - cairo_fill(cr); - } - - // draw top border - if(bdr_top) - { - set_color(cr, borders.top.color); - - double r_left = borders.radius.top_left_x; - double r_right = borders.radius.top_right_x; - - if(r_left) - { - double end_angle = M_PI * 3.0 / 2.0; - double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_left / (double) bdr_top + 1); - - add_path_arc(cr, - draw_pos.left() + r_left, - draw_pos.top() + r_left, - r_left, - r_left, - end_angle, - start_angle, true); - - add_path_arc(cr, - draw_pos.left() + r_left, - draw_pos.top() + r_left, - r_left - bdr_top + (bdr_top - bdr_left), - r_left - bdr_top, - start_angle, - end_angle, false); - } else - { - cairo_move_to(cr, draw_pos.left(), draw_pos.top()); - cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); - } - - if(r_right) - { - cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top); - - double start_angle = M_PI * 3.0 / 2.0; - double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_right / (double) bdr_top + 1); - - add_path_arc(cr, - draw_pos.right() - r_right, - draw_pos.top() + r_right, - r_right - bdr_top + (bdr_top - bdr_right), - r_right - bdr_top, - start_angle, - end_angle, false); - - add_path_arc(cr, - draw_pos.right() - r_right, - draw_pos.top() + r_right, - r_right, - r_right, - end_angle, - start_angle, true); - } else - { - cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); - cairo_line_to(cr, draw_pos.right(), draw_pos.top()); - } - - cairo_fill(cr); - } - - // draw left border - if(bdr_left) - { - set_color(cr, borders.left.color); - - double r_top = borders.radius.top_left_x; - double r_bottom = borders.radius.bottom_left_x; - - if(r_top) - { - double start_angle = M_PI; - double end_angle = start_angle + M_PI / 2.0 / ((double) bdr_top / (double) bdr_left + 1); - - add_path_arc(cr, - draw_pos.left() + r_top, - draw_pos.top() + r_top, - r_top - bdr_left, - r_top - bdr_left + (bdr_left - bdr_top), - start_angle, - end_angle, false); - - add_path_arc(cr, - draw_pos.left() + r_top, - draw_pos.top() + r_top, - r_top, - r_top, - end_angle, - start_angle, true); - } else - { - cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); - cairo_line_to(cr, draw_pos.left(), draw_pos.top()); - } - - if(r_bottom) - { - cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom); - - double end_angle = M_PI; - double start_angle = end_angle - M_PI / 2.0 / ((double) bdr_bottom / (double) bdr_left + 1); - - add_path_arc(cr, - draw_pos.left() + r_bottom, - draw_pos.bottom() - r_bottom, - r_bottom, - r_bottom, - end_angle, - start_angle, true); - - add_path_arc(cr, - draw_pos.left() + r_bottom, - draw_pos.bottom() - r_bottom, - r_bottom - bdr_left, - r_bottom - bdr_left + (bdr_left - bdr_bottom), - start_angle, - end_angle, false); - } else - { - cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); - cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); - } - - cairo_fill(cr); - } - cairo_restore(cr); + cairo_restore(cr); + } else { + cairo_move_to(cr, x, y); + } } -void container_linux::transform_text(litehtml::tstring& text, litehtml::text_transform tt) -{ +void container_linux::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) { + auto* cr = (cairo_t*)hdc; + cairo_save(cr); + apply_clip(cr); + cairo_new_path(cr); + + int bdr_top = 0; + int bdr_bottom = 0; + int bdr_left = 0; + int bdr_right = 0; + + if (borders.top.width != 0 && borders.top.style > litehtml::border_style_hidden) { + bdr_top = (int)borders.top.width; + } + if (borders.bottom.width != 0 && borders.bottom.style > litehtml::border_style_hidden) { + bdr_bottom = (int)borders.bottom.width; + } + if (borders.left.width != 0 && borders.left.style > litehtml::border_style_hidden) { + bdr_left = (int)borders.left.width; + } + if (borders.right.width != 0 && borders.right.style > litehtml::border_style_hidden) { + bdr_right = (int)borders.right.width; + } + + // draw right border + if (bdr_right) { + set_color(cr, borders.right.color); + + double r_top = borders.radius.top_right_x; + double r_bottom = borders.radius.bottom_right_x; + + if (r_top) { + double end_angle = 2 * M_PI; + double start_angle = end_angle - M_PI / 2.0 / ((double)bdr_top / (double)bdr_right + 1); + + add_path_arc(cr, draw_pos.right() - r_top, draw_pos.top() + r_top, r_top - bdr_right, r_top - bdr_right + (bdr_right - bdr_top), end_angle, start_angle, true); + + add_path_arc(cr, draw_pos.right() - r_top, draw_pos.top() + r_top, r_top, r_top, start_angle, end_angle, false); + } else { + cairo_move_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); + cairo_line_to(cr, draw_pos.right(), draw_pos.top()); + } + + if (r_bottom) { + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom() - r_bottom); + + double start_angle = 0; + double end_angle = start_angle + M_PI / 2.0 / ((double)bdr_bottom / (double)bdr_right + 1); + + add_path_arc(cr, draw_pos.right() - r_bottom, draw_pos.bottom() - r_bottom, r_bottom, r_bottom, start_angle, end_angle, false); + + add_path_arc(cr, draw_pos.right() - r_bottom, draw_pos.bottom() - r_bottom, r_bottom - bdr_right, r_bottom - bdr_right + (bdr_right - bdr_bottom), end_angle, start_angle, true); + } else { + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); + } + + cairo_fill(cr); + } + + // draw bottom border + if (bdr_bottom) { + set_color(cr, borders.bottom.color); + + double r_left = borders.radius.bottom_left_x; + double r_right = borders.radius.bottom_right_x; + + if (r_left) { + double start_angle = M_PI / 2.0; + double end_angle = start_angle + M_PI / 2.0 / ((double)bdr_left / (double)bdr_bottom + 1); + + add_path_arc(cr, draw_pos.left() + r_left, draw_pos.bottom() - r_left, r_left - bdr_bottom + (bdr_bottom - bdr_left), r_left - bdr_bottom, start_angle, end_angle, false); + + add_path_arc(cr, draw_pos.left() + r_left, draw_pos.bottom() - r_left, r_left, r_left, end_angle, start_angle, true); + } else { + cairo_move_to(cr, draw_pos.left(), draw_pos.bottom()); + cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); + } + + if (r_right) { + cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.bottom()); + + double end_angle = M_PI / 2.0; + double start_angle = end_angle - M_PI / 2.0 / ((double)bdr_right / (double)bdr_bottom + 1); + + add_path_arc(cr, draw_pos.right() - r_right, draw_pos.bottom() - r_right, r_right, r_right, end_angle, start_angle, true); + + add_path_arc(cr, draw_pos.right() - r_right, draw_pos.bottom() - r_right, r_right - bdr_bottom + (bdr_bottom - bdr_right), r_right - bdr_bottom, start_angle, end_angle, false); + } else { + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.bottom() - bdr_bottom); + cairo_line_to(cr, draw_pos.right(), draw_pos.bottom()); + } + + cairo_fill(cr); + } + + // draw top border + if (bdr_top) { + set_color(cr, borders.top.color); + + double r_left = borders.radius.top_left_x; + double r_right = borders.radius.top_right_x; + + if (r_left) { + double end_angle = M_PI * 3.0 / 2.0; + double start_angle = end_angle - M_PI / 2.0 / ((double)bdr_left / (double)bdr_top + 1); + + add_path_arc(cr, draw_pos.left() + r_left, draw_pos.top() + r_left, r_left, r_left, end_angle, start_angle, true); + + add_path_arc(cr, draw_pos.left() + r_left, draw_pos.top() + r_left, r_left - bdr_top + (bdr_top - bdr_left), r_left - bdr_top, start_angle, end_angle, false); + } else { + cairo_move_to(cr, draw_pos.left(), draw_pos.top()); + cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); + } + + if (r_right) { + cairo_line_to(cr, draw_pos.right() - r_right, draw_pos.top() + bdr_top); + + double start_angle = M_PI * 3.0 / 2.0; + double end_angle = start_angle + M_PI / 2.0 / ((double)bdr_right / (double)bdr_top + 1); + + add_path_arc(cr, draw_pos.right() - r_right, draw_pos.top() + r_right, r_right - bdr_top + (bdr_top - bdr_right), r_right - bdr_top, start_angle, end_angle, false); + + add_path_arc(cr, draw_pos.right() - r_right, draw_pos.top() + r_right, r_right, r_right, end_angle, start_angle, true); + } else { + cairo_line_to(cr, draw_pos.right() - bdr_right, draw_pos.top() + bdr_top); + cairo_line_to(cr, draw_pos.right(), draw_pos.top()); + } + + cairo_fill(cr); + } + + // draw left border + if (bdr_left) { + set_color(cr, borders.left.color); + + double r_top = borders.radius.top_left_x; + double r_bottom = borders.radius.bottom_left_x; + + if (r_top) { + double start_angle = M_PI; + double end_angle = start_angle + M_PI / 2.0 / ((double)bdr_top / (double)bdr_left + 1); + + add_path_arc(cr, draw_pos.left() + r_top, draw_pos.top() + r_top, r_top - bdr_left, r_top - bdr_left + (bdr_left - bdr_top), start_angle, end_angle, false); + + add_path_arc(cr, draw_pos.left() + r_top, draw_pos.top() + r_top, r_top, r_top, end_angle, start_angle, true); + } else { + cairo_move_to(cr, draw_pos.left() + bdr_left, draw_pos.top() + bdr_top); + cairo_line_to(cr, draw_pos.left(), draw_pos.top()); + } + + if (r_bottom) { + cairo_line_to(cr, draw_pos.left(), draw_pos.bottom() - r_bottom); + + double end_angle = M_PI; + double start_angle = end_angle - M_PI / 2.0 / ((double)bdr_bottom / (double)bdr_left + 1); + + add_path_arc(cr, draw_pos.left() + r_bottom, draw_pos.bottom() - r_bottom, r_bottom, r_bottom, end_angle, start_angle, true); + + add_path_arc(cr, draw_pos.left() + r_bottom, draw_pos.bottom() - r_bottom, r_bottom - bdr_left, r_bottom - bdr_left + (bdr_left - bdr_bottom), start_angle, end_angle, false); + } else { + cairo_line_to(cr, draw_pos.left(), draw_pos.bottom()); + cairo_line_to(cr, draw_pos.left() + bdr_left, draw_pos.bottom() - bdr_bottom); + } + + cairo_fill(cr); + } + cairo_restore(cr); } -void container_linux::set_clip( const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y ) -{ - litehtml::position clip_pos = pos; - litehtml::position client_pos; - get_client_rect(client_pos); - if(!valid_x) - { - clip_pos.x = client_pos.x; - clip_pos.width = client_pos.width; - } - if(!valid_y) - { - clip_pos.y = client_pos.y; - clip_pos.height = client_pos.height; - } - m_clips.emplace_back(clip_pos, bdr_radius); +void container_linux::transform_text(litehtml::tstring& text, litehtml::text_transform tt) {} + +void container_linux::set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) { + litehtml::position clip_pos = pos; + litehtml::position client_pos; + get_client_rect(client_pos); + if (!valid_x) { + clip_pos.x = client_pos.x; + clip_pos.width = client_pos.width; + } + if (!valid_y) { + clip_pos.y = client_pos.y; + clip_pos.height = client_pos.height; + } + m_clips.emplace_back(clip_pos, bdr_radius); } -void container_linux::del_clip() -{ - if(!m_clips.empty()) - { - m_clips.pop_back(); - } +void container_linux::del_clip() { + if (!m_clips.empty()) { + m_clips.pop_back(); + } } -void container_linux::apply_clip( cairo_t* cr ) -{ - for(const auto& clip_box : m_clips) - { - rounded_rectangle(cr, clip_box.box, clip_box.radius); - cairo_clip(cr); - } +void container_linux::apply_clip(cairo_t* cr) { + for (const auto& clip_box : m_clips) { + rounded_rectangle(cr, clip_box.box, clip_box.radius); + cairo_clip(cr); + } } -void container_linux::draw_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width ) -{ - if(!cr || !width || !height) return; - cairo_save(cr); +void container_linux::draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width) { + if (!cr || !width || !height) return; + cairo_save(cr); - apply_clip(cr); + apply_clip(cr); - cairo_new_path(cr); + cairo_new_path(cr); - cairo_translate (cr, x + width / 2.0, y + height / 2.0); - cairo_scale (cr, width / 2.0, height / 2.0); - cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); + cairo_translate(cr, x + width / 2.0, y + height / 2.0); + cairo_scale(cr, width / 2.0, height / 2.0); + cairo_arc(cr, 0, 0, 1, 0, 2 * M_PI); - set_color(cr, color); - cairo_set_line_width(cr, line_width); - cairo_stroke(cr); + set_color(cr, color); + cairo_set_line_width(cr, line_width); + cairo_stroke(cr); - cairo_restore(cr); + cairo_restore(cr); } -void container_linux::fill_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color ) -{ - if(!cr || !width || !height) return; - cairo_save(cr); +void container_linux::fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color) { + if (!cr || !width || !height) return; + cairo_save(cr); - apply_clip(cr); + apply_clip(cr); - cairo_new_path(cr); + cairo_new_path(cr); - cairo_translate (cr, x + width / 2.0, y + height / 2.0); - cairo_scale (cr, width / 2.0, height / 2.0); - cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI); + cairo_translate(cr, x + width / 2.0, y + height / 2.0); + cairo_scale(cr, width / 2.0, height / 2.0); + cairo_arc(cr, 0, 0, 1, 0, 2 * M_PI); - set_color(cr, color); - cairo_fill(cr); + set_color(cr, color); + cairo_fill(cr); - cairo_restore(cr); + cairo_restore(cr); } -void container_linux::clear_images() -{ -/* for(images_map::iterator i = m_images.begin(); i != m_images.end(); i++) - { - if(i->second) - { - delete i->second; - } - } - m_images.clear(); -*/ +void container_linux::clear_images() { + /* for(images_map::iterator i = m_images.begin(); i != m_images.end(); i++) + { + if(i->second) + { + delete i->second; + } + } + m_images.clear(); + */ } -const litehtml::tchar_t* container_linux::get_default_font_name() const -{ - return "Times New Roman"; +const litehtml::tchar_t* container_linux::get_default_font_name() const { return "Times New Roman"; } + +std::shared_ptr container_linux::create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) { return nullptr; } + +void container_linux::rounded_rectangle(cairo_t* cr, const litehtml::position& pos, const litehtml::border_radiuses& radius) { + cairo_new_path(cr); + if (radius.top_left_x) { + cairo_arc(cr, pos.left() + radius.top_left_x, pos.top() + radius.top_left_x, radius.top_left_x, M_PI, M_PI * 3.0 / 2.0); + } else { + cairo_move_to(cr, pos.left(), pos.top()); + } + + cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top()); + + if (radius.top_right_x) { + cairo_arc(cr, pos.right() - radius.top_right_x, pos.top() + radius.top_right_x, radius.top_right_x, M_PI * 3.0 / 2.0, 2.0 * M_PI); + } + + cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x); + + if (radius.bottom_right_x) { + cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0); + } + + cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom()); + + if (radius.bottom_left_x) { + cairo_arc(cr, pos.left() + radius.bottom_left_x, pos.bottom() - radius.bottom_left_x, radius.bottom_left_x, M_PI / 2.0, M_PI); + } } -std::shared_ptr container_linux::create_element(const litehtml::tchar_t *tag_name, - const litehtml::string_map &attributes, - const std::shared_ptr &doc) -{ - return nullptr; +void container_linux::draw_pixbuf(cairo_t* cr, const Glib::RefPtr& bmp, int x, int y, int cx, int cy) { + cairo_save(cr); + + { + Cairo::RefPtr crobj(new Cairo::Context(cr, false)); + + cairo_matrix_t flib_m; + cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); + + if (cx != bmp->get_width() || cy != bmp->get_height()) { + Glib::RefPtr new_img = bmp->scale_simple(cx, cy, Gdk::INTERP_BILINEAR); + Gdk::Cairo::set_source_pixbuf(crobj, new_img, x, y); + crobj->paint(); + } else { + Gdk::Cairo::set_source_pixbuf(crobj, bmp, x, y); + crobj->paint(); + } + } + + cairo_restore(cr); } -void container_linux::rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius ) -{ - cairo_new_path(cr); - if(radius.top_left_x) - { - cairo_arc(cr, pos.left() + radius.top_left_x, pos.top() + radius.top_left_x, radius.top_left_x, M_PI, M_PI * 3.0 / 2.0); - } else - { - cairo_move_to(cr, pos.left(), pos.top()); - } +cairo_surface_t* container_linux::surface_from_pixbuf(const Glib::RefPtr& bmp) { + cairo_surface_t* ret; - cairo_line_to(cr, pos.right() - radius.top_right_x, pos.top()); + if (bmp->get_has_alpha()) { + ret = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bmp->get_width(), bmp->get_height()); + } else { + ret = cairo_image_surface_create(CAIRO_FORMAT_RGB24, bmp->get_width(), bmp->get_height()); + } - if(radius.top_right_x) - { - cairo_arc(cr, pos.right() - radius.top_right_x, pos.top() + radius.top_right_x, radius.top_right_x, M_PI * 3.0 / 2.0, 2.0 * M_PI); - } + Cairo::RefPtr surface(new Cairo::Surface(ret, false)); + Cairo::RefPtr ctx = Cairo::Context::create(surface); + Gdk::Cairo::set_source_pixbuf(ctx, bmp, 0.0, 0.0); + ctx->paint(); - cairo_line_to(cr, pos.right(), pos.bottom() - radius.bottom_right_x); - - if(radius.bottom_right_x) - { - cairo_arc(cr, pos.right() - radius.bottom_right_x, pos.bottom() - radius.bottom_right_x, radius.bottom_right_x, 0, M_PI / 2.0); - } - - cairo_line_to(cr, pos.left() - radius.bottom_left_x, pos.bottom()); - - if(radius.bottom_left_x) - { - cairo_arc(cr, pos.left() + radius.bottom_left_x, pos.bottom() - radius.bottom_left_x, radius.bottom_left_x, M_PI / 2.0, M_PI); - } + return ret; } -void container_linux::draw_pixbuf(cairo_t* cr, const Glib::RefPtr& bmp, int x, int y, int cx, int cy) -{ - cairo_save(cr); - - { - Cairo::RefPtr crobj(new Cairo::Context(cr, false)); - - cairo_matrix_t flib_m; - cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); - - if(cx != bmp->get_width() || cy != bmp->get_height()) - { - Glib::RefPtr new_img = bmp->scale_simple(cx, cy, Gdk::INTERP_BILINEAR); - Gdk::Cairo::set_source_pixbuf(crobj, new_img, x, y); - crobj->paint(); - } else - { - Gdk::Cairo::set_source_pixbuf(crobj, bmp, x, y); - crobj->paint(); - } - } - - cairo_restore(cr); +void container_linux::get_media_features(litehtml::media_features& media) const { + litehtml::position client; + get_client_rect(client); + media.type = litehtml::media_type_screen; + media.width = client.width; + media.height = client.height; + media.device_width = Gdk::screen_width(); + media.device_height = Gdk::screen_height(); + media.color = 8; + media.monochrome = 0; + media.color_index = 256; + media.resolution = 96; } -cairo_surface_t* container_linux::surface_from_pixbuf(const Glib::RefPtr& bmp) -{ - cairo_surface_t* ret; - - if(bmp->get_has_alpha()) - { - ret = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bmp->get_width(), bmp->get_height()); - } else - { - ret = cairo_image_surface_create(CAIRO_FORMAT_RGB24, bmp->get_width(), bmp->get_height()); - } - - Cairo::RefPtr surface(new Cairo::Surface(ret, false)); - Cairo::RefPtr ctx = Cairo::Context::create(surface); - Gdk::Cairo::set_source_pixbuf(ctx, bmp, 0.0, 0.0); - ctx->paint(); - - return ret; +void container_linux::get_language(litehtml::tstring& language, litehtml::tstring& culture) const { + language = _t("en"); + culture = _t(""); } -void container_linux::get_media_features(litehtml::media_features& media) const -{ - litehtml::position client; - get_client_rect(client); - media.type = litehtml::media_type_screen; - media.width = client.width; - media.height = client.height; - media.device_width = Gdk::screen_width(); - media.device_height = Gdk::screen_height(); - media.color = 8; - media.monochrome = 0; - media.color_index = 256; - media.resolution = 96; -} - -void container_linux::get_language(litehtml::tstring& language, litehtml::tstring& culture) const -{ - language = _t("en"); - culture = _t(""); -} - -void container_linux::link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) -{ - -} +void container_linux::link(const std::shared_ptr& ptr, const litehtml::element::ptr& el) {} diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/linux/container_linux.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/linux/container_linux.h index 4b0a54416..d5f1c9a72 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/linux/container_linux.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/linux/container_linux.h @@ -1,104 +1,97 @@ #ifndef LH_CONTAINER_LINUX_H #define LH_CONTAINER_LINUX_H -#include "../../include/litehtml.h" #include #include #include -struct cairo_clip_box -{ - typedef std::vector vector; - litehtml::position box; - litehtml::border_radiuses radius; +#include "../../include/litehtml.h" - cairo_clip_box(const litehtml::position& vBox, const litehtml::border_radiuses& vRad) - { - box = vBox; - radius = vRad; - } +struct cairo_clip_box { + typedef std::vector vector; + litehtml::position box; + litehtml::border_radiuses radius; - cairo_clip_box(const cairo_clip_box& val) - { - box = val.box; - radius = val.radius; - } - cairo_clip_box& operator=(const cairo_clip_box& val) - { - box = val.box; - radius = val.radius; - return *this; - } + cairo_clip_box(const litehtml::position& vBox, const litehtml::border_radiuses& vRad) { + box = vBox; + radius = vRad; + } + + cairo_clip_box(const cairo_clip_box& val) { + box = val.box; + radius = val.radius; + } + cairo_clip_box& operator=(const cairo_clip_box& val) { + box = val.box; + radius = val.radius; + return *this; + } }; -struct cairo_font -{ - PangoFontDescription* font; - int size; - bool underline; - bool strikeout; - int ascent; - int descent; - int underline_thickness; - int underline_position; - int strikethrough_thickness; - int strikethrough_position; +struct cairo_font { + PangoFontDescription* font; + int size; + bool underline; + bool strikeout; + int ascent; + int descent; + int underline_thickness; + int underline_position; + int strikethrough_thickness; + int strikethrough_position; }; -class container_linux : public litehtml::document_container -{ - typedef std::map > images_map; +class container_linux : public litehtml::document_container { + typedef std::map > images_map; -protected: - cairo_surface_t* m_temp_surface; - cairo_t* m_temp_cr; - images_map m_images; - cairo_clip_box::vector m_clips; -public: - container_linux(); - virtual ~container_linux(); + protected: + cairo_surface_t* m_temp_surface; + cairo_t* m_temp_cr; + images_map m_images; + cairo_clip_box::vector m_clips; - litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; - void delete_font(litehtml::uint_ptr hFont) override; - int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; - void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; - int pt_to_px(int pt) const override; - int get_default_font_size() const override; - const litehtml::tchar_t* get_default_font_name() const override; - void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; - void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; - void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; - void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; - void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; - std::shared_ptr create_element(const litehtml::tchar_t *tag_name, - const litehtml::string_map &attributes, - const std::shared_ptr &doc) override; - void get_media_features(litehtml::media_features& media) const override; - void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; - void link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) override; + public: + container_linux(); + virtual ~container_linux(); + litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; + void delete_font(litehtml::uint_ptr hFont) override; + int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; + void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; + int pt_to_px(int pt) const override; + int get_default_font_size() const override; + const litehtml::tchar_t* get_default_font_name() const override; + void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; + void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; + void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; + void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; + void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; + std::shared_ptr create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) override; + void get_media_features(litehtml::media_features& media) const override; + void get_language(litehtml::tstring& language, litehtml::tstring& culture) const override; + void link(const std::shared_ptr& ptr, const litehtml::element::ptr& el) override; - void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; - void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; - void del_clip() override; + void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; + void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; + void del_clip() override; - virtual void make_url( const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out ); - virtual Glib::RefPtr get_image(const litehtml::tchar_t* url, bool redraw_on_ready) = 0; + virtual void make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out); + virtual Glib::RefPtr get_image(const litehtml::tchar_t* url, bool redraw_on_ready) = 0; - void clear_images(); + void clear_images(); -protected: - virtual void draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width); - virtual void fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color); - virtual void rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius ); + protected: + virtual void draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width); + virtual void fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color); + virtual void rounded_rectangle(cairo_t* cr, const litehtml::position& pos, const litehtml::border_radiuses& radius); -private: - void apply_clip(cairo_t* cr); + private: + void apply_clip(cairo_t* cr); - static void add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg); - static void set_color(cairo_t* cr, const litehtml::web_color& color) { cairo_set_source_rgba(cr, color.red / 255.0, color.green / 255.0, color.blue / 255.0, color.alpha / 255.0); } - static cairo_surface_t* surface_from_pixbuf(const Glib::RefPtr& bmp); - static void draw_pixbuf(cairo_t* cr, const Glib::RefPtr& bmp, int x, int y, int cx, int cy); + static void add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg); + static void set_color(cairo_t* cr, const litehtml::web_color& color) { cairo_set_source_rgba(cr, color.red / 255.0, color.green / 255.0, color.blue / 255.0, color.alpha / 255.0); } + static cairo_surface_t* surface_from_pixbuf(const Glib::RefPtr& bmp); + static void draw_pixbuf(cairo_t* cr, const Glib::RefPtr& bmp, int x, int y, int cx, int cy); }; #endif diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/test/container_test.cpp b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/test/container_test.cpp index e9cba80be..79c3762e5 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/test/container_test.cpp +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/test/container_test.cpp @@ -23,8 +23,8 @@ void container_test::get_image_size(const litehtml::tchar_t* src, const litehtml void container_test::draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) {} void container_test::make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out) { out = url; } void container_test::draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) {} -void container_test::set_caption(const litehtml::tchar_t* caption){}; //: set_caption -void container_test::set_base_url(const litehtml::tchar_t* base_url){}; //: set_base_url +void container_test::set_caption(const litehtml::tchar_t* caption) {}; //: set_caption +void container_test::set_base_url(const litehtml::tchar_t* base_url) {}; //: set_base_url void container_test::link(const std::shared_ptr& ptr, const litehtml::element::ptr& el) {} void container_test::on_anchor_click(const litehtml::tchar_t* url, const litehtml::element::ptr& el) {} //: on_anchor_click void container_test::set_cursor(const litehtml::tchar_t* cursor) {} //: set_cursor diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/test/container_test.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/test/container_test.h index 73675af05..0efdcd770 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/test/container_test.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/test/container_test.h @@ -2,43 +2,38 @@ #include "../../include/litehtml.h" -class container_test : public litehtml::document_container -{ -public: - container_test(); - virtual ~container_test(); +class container_test : public litehtml::document_container { + public: + container_test(); + virtual ~container_test(); - virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; - virtual void delete_font(litehtml::uint_ptr hFont) override; - virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; - virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; - virtual int pt_to_px(int pt) const override; - virtual int get_default_font_size() const override; - virtual const litehtml::tchar_t* get_default_font_name() const override; - virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; - virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; - virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; - virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; - virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; - virtual std::shared_ptr create_element(const litehtml::tchar_t *tag_name, - const litehtml::string_map &attributes, - const std::shared_ptr &doc) override; - virtual void get_media_features(litehtml::media_features& media) const override; - virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const override; - virtual void link(const std::shared_ptr &ptr, const litehtml::element::ptr& el) override; + virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override; + virtual void delete_font(litehtml::uint_ptr hFont) override; + virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override; + virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override; + virtual int pt_to_px(int pt) const override; + virtual int get_default_font_size() const override; + virtual const litehtml::tchar_t* get_default_font_name() const override; + virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override; + virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override; + virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) override; + virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) override; + virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) override; + virtual std::shared_ptr create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) override; + virtual void get_media_features(litehtml::media_features& media) const override; + virtual void get_language(litehtml::tstring& language, litehtml::tstring& culture) const override; + virtual void link(const std::shared_ptr& ptr, const litehtml::element::ptr& el) override; + virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; + virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; + virtual void del_clip() override; - virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) override; - virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) override; - virtual void del_clip() override; + virtual void make_url(const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out); - virtual void make_url( const litehtml::tchar_t* url, const litehtml::tchar_t* basepath, litehtml::tstring& out ); - - - virtual void set_caption(const litehtml::tchar_t* caption) override; - virtual void set_base_url(const litehtml::tchar_t* base_url) override; - virtual void on_anchor_click(const litehtml::tchar_t* url, const litehtml::element::ptr& el) override; - virtual void set_cursor(const litehtml::tchar_t* cursor) override; - virtual void import_css(litehtml::tstring& text, const litehtml::tstring& url, litehtml::tstring& baseurl) override; - virtual void get_client_rect(litehtml::position& client) const override; + virtual void set_caption(const litehtml::tchar_t* caption) override; + virtual void set_base_url(const litehtml::tchar_t* base_url) override; + virtual void on_anchor_click(const litehtml::tchar_t* url, const litehtml::element::ptr& el) override; + virtual void set_cursor(const litehtml::tchar_t* cursor) override; + virtual void import_css(litehtml::tstring& text, const litehtml::tstring& url, litehtml::tstring& baseurl) override; + virtual void get_client_rect(litehtml::position& client) const override; }; diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/win32/win32_container.cpp b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/win32/win32_container.cpp index eb8e0b33b..ebc478e34 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/win32/win32_container.cpp +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/win32/win32_container.cpp @@ -1,327 +1,259 @@ -#include #include "win32_container.h" +#include -litehtml::win32_container::win32_container() -{ - m_hClipRgn = NULL; +litehtml::win32_container::win32_container() { m_hClipRgn = NULL; } + +litehtml::win32_container::~win32_container() { + if (m_hClipRgn) { + DeleteObject(m_hClipRgn); + } } -litehtml::win32_container::~win32_container() -{ - if(m_hClipRgn) - { - DeleteObject(m_hClipRgn); - } +litehtml::uint_ptr litehtml::win32_container::create_font(const wchar_t* faceName, int size, int weight, font_style italic, unsigned int decoration) { + litehtml::string_vector fonts; + tokenize(faceName, fonts, L","); + litehtml::trim(fonts[0]); + + LOGFONT lf; + ZeroMemory(&lf, sizeof(lf)); + wcscpy_s(lf.lfFaceName, LF_FACESIZE, fonts[0].c_str()); + + lf.lfHeight = -size; + lf.lfWeight = weight; + lf.lfItalic = (italic == litehtml::fontStyleItalic) ? TRUE : FALSE; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfStrikeOut = (decoration & litehtml::font_decoration_linethrough) ? TRUE : FALSE; + lf.lfUnderline = (decoration & litehtml::font_decoration_underline) ? TRUE : FALSE; + HFONT hFont = CreateFontIndirect(&lf); + + return (uint_ptr)hFont; } -litehtml::uint_ptr litehtml::win32_container::create_font( const wchar_t* faceName, int size, int weight, font_style italic, unsigned int decoration ) -{ - litehtml::string_vector fonts; - tokenize(faceName, fonts, L","); - litehtml::trim(fonts[0]); +void litehtml::win32_container::delete_font(uint_ptr hFont) { DeleteObject((HFONT)hFont); } - LOGFONT lf; - ZeroMemory(&lf, sizeof(lf)); - wcscpy_s(lf.lfFaceName, LF_FACESIZE, fonts[0].c_str()); - - lf.lfHeight = -size; - lf.lfWeight = weight; - lf.lfItalic = (italic == litehtml::fontStyleItalic) ? TRUE : FALSE; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfOutPrecision = OUT_DEFAULT_PRECIS; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - lf.lfStrikeOut = (decoration & litehtml::font_decoration_linethrough) ? TRUE : FALSE; - lf.lfUnderline = (decoration & litehtml::font_decoration_underline) ? TRUE : FALSE; - HFONT hFont = CreateFontIndirect(&lf); - - return (uint_ptr) hFont; +int litehtml::win32_container::line_height(uint_ptr hdc, uint_ptr hFont) { + HFONT oldFont = (HFONT)SelectObject((HDC)hdc, (HFONT)hFont); + TEXTMETRIC tm; + GetTextMetrics((HDC)hdc, &tm); + SelectObject((HDC)hdc, oldFont); + return (int)tm.tmHeight; } -void litehtml::win32_container::delete_font( uint_ptr hFont ) -{ - DeleteObject((HFONT) hFont); +int litehtml::win32_container::text_width(uint_ptr hdc, const wchar_t* text, uint_ptr hFont) { + HFONT oldFont = (HFONT)SelectObject((HDC)hdc, (HFONT)hFont); + + SIZE sz = {0, 0}; + + GetTextExtentPoint32((HDC)hdc, text, lstrlen(text), &sz); + + SelectObject((HDC)hdc, oldFont); + + return (int)sz.cx; } -int litehtml::win32_container::line_height( uint_ptr hdc, uint_ptr hFont ) -{ - HFONT oldFont = (HFONT) SelectObject((HDC) hdc, (HFONT) hFont); - TEXTMETRIC tm; - GetTextMetrics((HDC) hdc, &tm); - SelectObject((HDC) hdc, oldFont); - return (int) tm.tmHeight; +void litehtml::win32_container::draw_text(uint_ptr hdc, const wchar_t* text, uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) { + apply_clip((HDC)hdc); + + HFONT oldFont = (HFONT)SelectObject((HDC)hdc, (HFONT)hFont); + + SetBkMode((HDC)hdc, TRANSPARENT); + + SetTextColor((HDC)hdc, RGB(color.red, color.green, color.blue)); + + RECT rcText = {pos.left(), pos.top(), pos.right(), pos.bottom()}; + DrawText((HDC)hdc, text, -1, &rcText, DT_SINGLELINE | DT_NOPREFIX | DT_BOTTOM | DT_NOCLIP); + + SelectObject((HDC)hdc, oldFont); + + release_clip((HDC)hdc); } -int litehtml::win32_container::text_width( uint_ptr hdc, const wchar_t* text, uint_ptr hFont ) -{ - HFONT oldFont = (HFONT) SelectObject((HDC) hdc, (HFONT) hFont); - - SIZE sz = {0, 0}; - - GetTextExtentPoint32((HDC) hdc, text, lstrlen(text), &sz); - - SelectObject((HDC) hdc, oldFont); - - return (int) sz.cx; +void litehtml::win32_container::fill_rect(uint_ptr hdc, const litehtml::position& pos, const litehtml::web_color color, const litehtml::css_border_radius& radius) { + apply_clip((HDC)hdc); + fill_rect((HDC)hdc, pos.x, pos.y, pos.width, pos.height, color, radius); + release_clip((HDC)hdc); } -void litehtml::win32_container::draw_text( uint_ptr hdc, const wchar_t* text, uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos ) -{ - apply_clip((HDC) hdc); +litehtml::uint_ptr litehtml::win32_container::get_temp_dc() { return (litehtml::uint_ptr)GetDC(NULL); } - HFONT oldFont = (HFONT) SelectObject((HDC) hdc, (HFONT) hFont); +void litehtml::win32_container::release_temp_dc(uint_ptr hdc) { ReleaseDC(NULL, (HDC)hdc); } - SetBkMode((HDC) hdc, TRANSPARENT); - - SetTextColor((HDC) hdc, RGB(color.red, color.green, color.blue)); - - RECT rcText = { pos.left(), pos.top(), pos.right(), pos.bottom() }; - DrawText((HDC) hdc, text, -1, &rcText, DT_SINGLELINE | DT_NOPREFIX | DT_BOTTOM | DT_NOCLIP); - - SelectObject((HDC) hdc, oldFont); - - release_clip((HDC) hdc); +int litehtml::win32_container::pt_to_px(int pt) { + HDC dc = GetDC(NULL); + int ret = MulDiv(pt, GetDeviceCaps(dc, LOGPIXELSY), 72); + ReleaseDC(NULL, dc); + return ret; } -void litehtml::win32_container::fill_rect( uint_ptr hdc, const litehtml::position& pos, const litehtml::web_color color, const litehtml::css_border_radius& radius ) -{ - apply_clip((HDC) hdc); - fill_rect((HDC) hdc, pos.x, pos.y, pos.width, pos.height, color, radius); - release_clip((HDC) hdc); +int litehtml::win32_container::get_text_base_line(uint_ptr hdc, uint_ptr hFont) { + HDC dc = (HDC)hdc; + if (!dc) { + dc = GetDC(NULL); + } + HFONT oldFont = (HFONT)SelectObject(dc, (HFONT)hFont); + TEXTMETRIC tm; + GetTextMetrics(dc, &tm); + SelectObject(dc, oldFont); + if (!hdc) { + ReleaseDC(NULL, dc); + } + return (int)tm.tmDescent; } -litehtml::uint_ptr litehtml::win32_container::get_temp_dc() -{ - return (litehtml::uint_ptr) GetDC(NULL); +void litehtml::win32_container::draw_list_marker(uint_ptr hdc, const litehtml::list_marker& marker) { + apply_clip((HDC)hdc); + + int top_margin = marker.pos.height / 3; + if (top_margin < 4) top_margin = 0; + + int draw_x = marker.pos.x; + int draw_y = marker.pos.y + top_margin; + int draw_width = marker.pos.height - top_margin * 2; + int draw_height = marker.pos.height - top_margin * 2; + + switch (marker.marker_type) { + case list_style_type_circle: { + draw_ellipse((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color, 1); + } break; + case list_style_type_disc: { + fill_ellipse((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color); + } break; + case list_style_type_square: { + fill_rect((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color, css_border_radius()); + } break; + } + release_clip((HDC)hdc); } -void litehtml::win32_container::release_temp_dc( uint_ptr hdc ) -{ - ReleaseDC(NULL, (HDC) hdc); +void litehtml::win32_container::load_image(const wchar_t* src, const wchar_t* baseurl, bool redraw_on_ready) { + std::wstring url; + make_url(src, baseurl, url); + if (m_images.find(url.c_str()) == m_images.end()) { + uint_ptr img = get_image(url.c_str()); + if (img) { + m_images[url.c_str()] = img; + } + } } -int litehtml::win32_container::pt_to_px( int pt ) -{ - HDC dc = GetDC(NULL); - int ret = MulDiv(pt, GetDeviceCaps(dc, LOGPIXELSY), 72); - ReleaseDC(NULL, dc); - return ret; +void litehtml::win32_container::get_image_size(const wchar_t* src, const wchar_t* baseurl, litehtml::size& sz) { + std::wstring url; + make_url(src, baseurl, url); + + images_map::iterator img = m_images.find(url.c_str()); + if (img != m_images.end()) { + get_img_size(img->second, sz); + } } -int litehtml::win32_container::get_text_base_line( uint_ptr hdc, uint_ptr hFont ) -{ - HDC dc = (HDC) hdc; - if(!dc) - { - dc = GetDC(NULL); - } - HFONT oldFont = (HFONT) SelectObject(dc, (HFONT) hFont); - TEXTMETRIC tm; - GetTextMetrics(dc, &tm); - SelectObject(dc, oldFont); - if(!hdc) - { - ReleaseDC(NULL, dc); - } - return (int) tm.tmDescent; +void litehtml::win32_container::draw_image(uint_ptr hdc, const wchar_t* src, const wchar_t* baseurl, const litehtml::position& pos) { + apply_clip((HDC)hdc); + + std::wstring url; + make_url(src, baseurl, url); + images_map::iterator img = m_images.find(url.c_str()); + if (img != m_images.end()) { + draw_img((HDC)hdc, img->second, pos); + } + + release_clip((HDC)hdc); } -void litehtml::win32_container::draw_list_marker(uint_ptr hdc, const litehtml::list_marker& marker) -{ - apply_clip((HDC)hdc); - - int top_margin = marker.pos.height / 3; - if (top_margin < 4) - top_margin = 0; - - int draw_x = marker.pos.x; - int draw_y = marker.pos.y + top_margin; - int draw_width = marker.pos.height - top_margin * 2; - int draw_height = marker.pos.height - top_margin * 2; - - switch (marker.marker_type) - { - case list_style_type_circle: - { - draw_ellipse((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color, 1); - } - break; - case list_style_type_disc: - { - fill_ellipse((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color); - } - break; - case list_style_type_square: - { - fill_rect((HDC)hdc, draw_x, draw_y, draw_width, draw_height, marker.color, css_border_radius()); - } - break; - } - release_clip((HDC)hdc); +void litehtml::win32_container::clear_images() { + for (images_map::iterator i = m_images.begin(); i != m_images.end(); i++) { + if (i->second) { + free_image(i->second); + } + } + m_images.clear(); } -void litehtml::win32_container::load_image( const wchar_t* src, const wchar_t* baseurl, bool redraw_on_ready ) -{ - std::wstring url; - make_url(src, baseurl, url); - if(m_images.find(url.c_str()) == m_images.end()) - { - uint_ptr img = get_image(url.c_str()); - if(img) - { - m_images[url.c_str()] = img; - } - } +int litehtml::win32_container::get_default_font_size() const { return 16; } + +void litehtml::win32_container::draw_background(uint_ptr hdc, const wchar_t* image, const wchar_t* baseurl, const litehtml::position& draw_pos, const litehtml::css_position& bg_pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment) { + apply_clip((HDC)hdc); + + std::wstring url; + make_url(image, baseurl, url); + + images_map::iterator img = m_images.find(url.c_str()); + if (img != m_images.end()) { + litehtml::size img_sz; + get_img_size(img->second, img_sz); + + litehtml::position pos = draw_pos; + + if (bg_pos.x.units() != css_units_percentage) { + pos.x += (int)bg_pos.x.val(); + } else { + pos.x += (int)((float)(draw_pos.width - img_sz.width) * bg_pos.x.val() / 100.0); + } + + if (bg_pos.y.units() != css_units_percentage) { + pos.y += (int)bg_pos.y.val(); + } else { + pos.y += (int)((float)(draw_pos.height - img_sz.height) * bg_pos.y.val() / 100.0); + } + + draw_img_bg((HDC)hdc, img->second, draw_pos, pos, repeat, attachment); + } + + release_clip((HDC)hdc); } -void litehtml::win32_container::get_image_size( const wchar_t* src, const wchar_t* baseurl, litehtml::size& sz ) -{ - std::wstring url; - make_url(src, baseurl, url); +wchar_t litehtml::win32_container::toupper(const wchar_t c) { return (wchar_t)CharUpper((LPWSTR)c); } - images_map::iterator img = m_images.find(url.c_str()); - if(img != m_images.end()) - { - get_img_size(img->second, sz); - } +wchar_t litehtml::win32_container::tolower(const wchar_t c) { return (wchar_t)CharLower((LPWSTR)c); } + +void litehtml::win32_container::set_clip(const litehtml::position& pos, bool valid_x, bool valid_y) { + litehtml::position clip_pos = pos; + litehtml::position client_pos; + get_client_rect(client_pos); + if (!valid_x) { + clip_pos.x = client_pos.x; + clip_pos.width = client_pos.width; + } + if (!valid_y) { + clip_pos.y = client_pos.y; + clip_pos.height = client_pos.height; + } + m_clips.push_back(clip_pos); } -void litehtml::win32_container::draw_image( uint_ptr hdc, const wchar_t* src, const wchar_t* baseurl, const litehtml::position& pos ) -{ - apply_clip((HDC) hdc); - - std::wstring url; - make_url(src, baseurl, url); - images_map::iterator img = m_images.find(url.c_str()); - if(img != m_images.end()) - { - draw_img((HDC) hdc, img->second, pos); - } - - release_clip((HDC) hdc); +void litehtml::win32_container::del_clip() { + if (!m_clips.empty()) { + m_clips.pop_back(); + if (!m_clips.empty()) { + litehtml::position clip_pos = m_clips.back(); + } + } } -void litehtml::win32_container::clear_images() -{ - for(images_map::iterator i = m_images.begin(); i != m_images.end(); i++) - { - if(i->second) - { - free_image(i->second); - } - } - m_images.clear(); +void litehtml::win32_container::apply_clip(HDC hdc) { + if (m_hClipRgn) { + DeleteObject(m_hClipRgn); + m_hClipRgn = NULL; + } + + if (!m_clips.empty()) { + POINT ptView = {0, 0}; + GetWindowOrgEx(hdc, &ptView); + + litehtml::position clip_pos = m_clips.back(); + m_hClipRgn = CreateRectRgn(clip_pos.left() - ptView.x, clip_pos.top() - ptView.y, clip_pos.right() - ptView.x, clip_pos.bottom() - ptView.y); + SelectClipRgn(hdc, m_hClipRgn); + } } -int litehtml::win32_container::get_default_font_size() const -{ - return 16; -} - -void litehtml::win32_container::draw_background( uint_ptr hdc, const wchar_t* image, const wchar_t* baseurl, const litehtml::position& draw_pos, const litehtml::css_position& bg_pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment ) -{ - apply_clip((HDC) hdc); - - std::wstring url; - make_url(image, baseurl, url); - - images_map::iterator img = m_images.find(url.c_str()); - if(img != m_images.end()) - { - litehtml::size img_sz; - get_img_size(img->second, img_sz); - - litehtml::position pos = draw_pos; - - if(bg_pos.x.units() != css_units_percentage) - { - pos.x += (int) bg_pos.x.val(); - } else - { - pos.x += (int) ((float) (draw_pos.width - img_sz.width) * bg_pos.x.val() / 100.0); - } - - if(bg_pos.y.units() != css_units_percentage) - { - pos.y += (int) bg_pos.y.val(); - } else - { - pos.y += (int) ( (float) (draw_pos.height - img_sz.height) * bg_pos.y.val() / 100.0); - } - - draw_img_bg((HDC) hdc, img->second, draw_pos, pos, repeat, attachment); - } - - release_clip((HDC) hdc); -} - -wchar_t litehtml::win32_container::toupper( const wchar_t c ) -{ - return (wchar_t) CharUpper((LPWSTR) c); -} - -wchar_t litehtml::win32_container::tolower( const wchar_t c ) -{ - return (wchar_t) CharLower((LPWSTR) c); -} - -void litehtml::win32_container::set_clip( const litehtml::position& pos, bool valid_x, bool valid_y ) -{ - litehtml::position clip_pos = pos; - litehtml::position client_pos; - get_client_rect(client_pos); - if(!valid_x) - { - clip_pos.x = client_pos.x; - clip_pos.width = client_pos.width; - } - if(!valid_y) - { - clip_pos.y = client_pos.y; - clip_pos.height = client_pos.height; - } - m_clips.push_back(clip_pos); -} - -void litehtml::win32_container::del_clip() -{ - if(!m_clips.empty()) - { - m_clips.pop_back(); - if(!m_clips.empty()) - { - litehtml::position clip_pos = m_clips.back(); - } - } -} - -void litehtml::win32_container::apply_clip(HDC hdc) -{ - if(m_hClipRgn) - { - DeleteObject(m_hClipRgn); - m_hClipRgn = NULL; - } - - if(!m_clips.empty()) - { - POINT ptView = {0, 0}; - GetWindowOrgEx(hdc, &ptView); - - litehtml::position clip_pos = m_clips.back(); - m_hClipRgn = CreateRectRgn(clip_pos.left() - ptView.x, clip_pos.top() - ptView.y, clip_pos.right() - ptView.x, clip_pos.bottom() - ptView.y); - SelectClipRgn(hdc, m_hClipRgn); - } -} - -void litehtml::win32_container::release_clip(HDC hdc) -{ - SelectClipRgn(hdc, NULL); - - if(m_hClipRgn) - { - DeleteObject(m_hClipRgn); - m_hClipRgn = NULL; - } +void litehtml::win32_container::release_clip(HDC hdc) { + SelectClipRgn(hdc, NULL); + + if (m_hClipRgn) { + DeleteObject(m_hClipRgn); + m_hClipRgn = NULL; + } } diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/win32/win32_container.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/win32/win32_container.h index e2a361329..31972c576 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/win32/win32_container.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/containers/win32/win32_container.h @@ -1,65 +1,56 @@ #pragma once #include -namespace litehtml -{ - class win32_container : public document_container - { - public: - typedef std::map images_map; - - protected: - - images_map m_images; - litehtml::position::vector m_clips; - HRGN m_hClipRgn; +namespace litehtml { +class win32_container : public document_container { + public: + typedef std::map images_map; - public: - win32_container(); - virtual ~win32_container(); + protected: + images_map m_images; + litehtml::position::vector m_clips; + HRGN m_hClipRgn; - // litehtml::document_container members - virtual uint_ptr create_font(const wchar_t* faceName, int size, int weight, font_style italic, unsigned int decoration); - virtual void delete_font(uint_ptr hFont); - virtual int line_height(uint_ptr hdc, uint_ptr hFont); - virtual int get_text_base_line(uint_ptr hdc, uint_ptr hFont); - virtual int text_width(uint_ptr hdc, const wchar_t* text, uint_ptr hFont); - virtual void draw_text(uint_ptr hdc, const wchar_t* text, uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos); - virtual void fill_rect(uint_ptr hdc, const litehtml::position& pos, const litehtml::web_color color, const litehtml::css_border_radius& radius); - virtual uint_ptr get_temp_dc(); - virtual void release_temp_dc(uint_ptr hdc); - virtual int pt_to_px(int pt); - virtual void draw_list_marker(uint_ptr hdc, const litehtml::list_marker& marker); - virtual void load_image(const wchar_t* src, const wchar_t* baseurl, bool redraw_on_ready); - virtual void get_image_size(const wchar_t* src, const wchar_t* baseurl, litehtml::size& sz); - virtual void draw_image(uint_ptr hdc, const wchar_t* src, const wchar_t* baseurl, const litehtml::position& pos); - virtual void draw_background(uint_ptr hdc, - const wchar_t* image, - const wchar_t* baseurl, - const litehtml::position& draw_pos, - const litehtml::css_position& bg_pos, - litehtml::background_repeat repeat, - litehtml::background_attachment attachment); + public: + win32_container(); + virtual ~win32_container(); - virtual int get_default_font_size() const; - virtual wchar_t toupper(const wchar_t c); - virtual wchar_t tolower(const wchar_t c); - virtual void set_clip(const litehtml::position& pos, bool valid_x, bool valid_y); - virtual void del_clip(); + // litehtml::document_container members + virtual uint_ptr create_font(const wchar_t* faceName, int size, int weight, font_style italic, unsigned int decoration); + virtual void delete_font(uint_ptr hFont); + virtual int line_height(uint_ptr hdc, uint_ptr hFont); + virtual int get_text_base_line(uint_ptr hdc, uint_ptr hFont); + virtual int text_width(uint_ptr hdc, const wchar_t* text, uint_ptr hFont); + virtual void draw_text(uint_ptr hdc, const wchar_t* text, uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos); + virtual void fill_rect(uint_ptr hdc, const litehtml::position& pos, const litehtml::web_color color, const litehtml::css_border_radius& radius); + virtual uint_ptr get_temp_dc(); + virtual void release_temp_dc(uint_ptr hdc); + virtual int pt_to_px(int pt); + virtual void draw_list_marker(uint_ptr hdc, const litehtml::list_marker& marker); + virtual void load_image(const wchar_t* src, const wchar_t* baseurl, bool redraw_on_ready); + virtual void get_image_size(const wchar_t* src, const wchar_t* baseurl, litehtml::size& sz); + virtual void draw_image(uint_ptr hdc, const wchar_t* src, const wchar_t* baseurl, const litehtml::position& pos); + virtual void draw_background(uint_ptr hdc, const wchar_t* image, const wchar_t* baseurl, const litehtml::position& draw_pos, const litehtml::css_position& bg_pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment); - protected: - void apply_clip(HDC hdc); - void release_clip(HDC hdc); - void clear_images(); - virtual void make_url( LPCWSTR url, LPCWSTR basepath, std::wstring& out ) = 0; - virtual uint_ptr get_image(LPCWSTR url) = 0; - virtual void free_image(uint_ptr img) = 0; - virtual void get_client_rect(litehtml::position& client) = 0; - virtual void draw_ellipse(HDC hdc, int x, int y, int width, int height, const web_color& color, int line_width) = 0; - virtual void fill_ellipse(HDC hdc, int x, int y, int width, int height, const web_color& color) = 0; - virtual void fill_rect(HDC hdc, int x, int y, int width, int height, const web_color& color, const litehtml::css_border_radius& radius) = 0; - virtual void get_img_size(litehtml::uint_ptr img, litehtml::size& sz) = 0; - virtual void draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos) = 0; - virtual void draw_img_bg(HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment) = 0; - }; -} \ No newline at end of file + virtual int get_default_font_size() const; + virtual wchar_t toupper(const wchar_t c); + virtual wchar_t tolower(const wchar_t c); + virtual void set_clip(const litehtml::position& pos, bool valid_x, bool valid_y); + virtual void del_clip(); + + protected: + void apply_clip(HDC hdc); + void release_clip(HDC hdc); + void clear_images(); + virtual void make_url(LPCWSTR url, LPCWSTR basepath, std::wstring& out) = 0; + virtual uint_ptr get_image(LPCWSTR url) = 0; + virtual void free_image(uint_ptr img) = 0; + virtual void get_client_rect(litehtml::position& client) = 0; + virtual void draw_ellipse(HDC hdc, int x, int y, int width, int height, const web_color& color, int line_width) = 0; + virtual void fill_ellipse(HDC hdc, int x, int y, int width, int height, const web_color& color) = 0; + virtual void fill_rect(HDC hdc, int x, int y, int width, int height, const web_color& color, const litehtml::css_border_radius& radius) = 0; + virtual void get_img_size(litehtml::uint_ptr img, litehtml::size& sz) = 0; + virtual void draw_img(HDC hdc, litehtml::uint_ptr img, const litehtml::position& pos) = 0; + virtual void draw_img_bg(HDC hdc, litehtml::uint_ptr img, const litehtml::position& draw_pos, const litehtml::position& pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment) = 0; +}; +} // namespace litehtml \ No newline at end of file diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml.h index 98a24e0da..0737513a8 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml.h @@ -1,10 +1,10 @@ #ifndef LITEHTML_H #define LITEHTML_H -#include #include +#include +#include #include #include -#include #endif // LITEHTML_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/attributes.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/attributes.h index 98487f02e..a3ab3746b 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/attributes.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/attributes.h @@ -1,35 +1,30 @@ #ifndef LH_ATTRIBUTES_H #define LH_ATTRIBUTES_H -namespace litehtml -{ - struct attr_color - { - unsigned char rgbBlue; - unsigned char rgbGreen; - unsigned char rgbRed; - unsigned char rgbAlpha; - attr_color() - { - rgbAlpha = 255; - rgbBlue = 0; - rgbGreen = 0; - rgbRed = 0; - } - }; +namespace litehtml { +struct attr_color { + unsigned char rgbBlue; + unsigned char rgbGreen; + unsigned char rgbRed; + unsigned char rgbAlpha; + attr_color() { + rgbAlpha = 255; + rgbBlue = 0; + rgbGreen = 0; + rgbRed = 0; + } +}; - struct attr_border - { - style_border border; - int width; - attr_color color; +struct attr_border { + style_border border; + int width; + attr_color color; - attr_border() - { - border = borderNone; - width = 0; - } - }; -} + attr_border() { + border = borderNone; + width = 0; + } +}; +} // namespace litehtml #endif // LH_ATTRIBUTES_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/background.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/background.h index 35b022b3c..6b05db235 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/background.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/background.h @@ -1,58 +1,56 @@ #ifndef LH_BACKGROUND_H #define LH_BACKGROUND_H -#include "types.h" #include "attributes.h" +#include "borders.h" #include "css_length.h" #include "css_position.h" +#include "types.h" #include "web_color.h" -#include "borders.h" -namespace litehtml -{ - class background - { - public: - tstring m_image; - tstring m_baseurl; - web_color m_color; - background_attachment m_attachment; - css_position m_position; - background_repeat m_repeat; - background_box m_clip; - background_box m_origin; - css_border_radius m_radius; +namespace litehtml { +class background { + public: + tstring m_image; + tstring m_baseurl; + web_color m_color; + background_attachment m_attachment; + css_position m_position; + background_repeat m_repeat; + background_box m_clip; + background_box m_origin; + css_border_radius m_radius; - public: - background(); - background(const background& val); - ~background() = default; + public: + background(); + background(const background& val); + ~background() = default; - background& operator=(const background& val); - }; + background& operator=(const background& val); +}; - class background_paint - { - public: - tstring image; - tstring baseurl; - background_attachment attachment; - background_repeat repeat; - web_color color; - position clip_box; - position origin_box; - position border_box; - border_radiuses border_radius; - size image_size; - int position_x; - int position_y; - bool is_root; - public: - background_paint(); - background_paint(const background_paint& val); - background_paint& operator=(const background& val); - }; +class background_paint { + public: + tstring image; + tstring baseurl; + background_attachment attachment; + background_repeat repeat; + web_color color; + position clip_box; + position origin_box; + position border_box; + border_radiuses border_radius; + size image_size; + int position_x; + int position_y; + bool is_root; -} + public: + background_paint(); + background_paint(const background_paint& val); + background_paint& operator=(const background& val); +}; + +} // namespace litehtml #endif // LH_BACKGROUND_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/borders.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/borders.h index 72618670d..02b70ca45 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/borders.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/borders.h @@ -4,302 +4,259 @@ #include "css_length.h" #include "types.h" -namespace litehtml -{ - struct css_border - { - css_length width; - border_style style; - web_color color; +namespace litehtml { +struct css_border { + css_length width; + border_style style; + web_color color; - css_border() - { - style = border_style_none; - } + css_border() { style = border_style_none; } - css_border(const css_border& val) - { - width = val.width; - style = val.style; - color = val.color; - } + css_border(const css_border& val) { + width = val.width; + style = val.style; + color = val.color; + } - css_border& operator=(const css_border& val) - { - width = val.width; - style = val.style; - color = val.color; - return *this; - } - }; + css_border& operator=(const css_border& val) { + width = val.width; + style = val.style; + color = val.color; + return *this; + } +}; - struct border - { - int width; - border_style style; - web_color color; +struct border { + int width; + border_style style; + web_color color; - border() - { - width = 0; - } - border(const border& val) - { - width = val.width; - style = val.style; - color = val.color; - } - border(const css_border& val) - { - width = (int) val.width.val(); - style = val.style; - color = val.color; - } - border& operator=(const border& val) - { - width = val.width; - style = val.style; - color = val.color; - return *this; - } - border& operator=(const css_border& val) - { - width = (int) val.width.val(); - style = val.style; - color = val.color; - return *this; - } - }; + border() { width = 0; } + border(const border& val) { + width = val.width; + style = val.style; + color = val.color; + } + border(const css_border& val) { + width = (int)val.width.val(); + style = val.style; + color = val.color; + } + border& operator=(const border& val) { + width = val.width; + style = val.style; + color = val.color; + return *this; + } + border& operator=(const css_border& val) { + width = (int)val.width.val(); + style = val.style; + color = val.color; + return *this; + } +}; - struct border_radiuses - { - int top_left_x; - int top_left_y; +struct border_radiuses { + int top_left_x; + int top_left_y; - int top_right_x; - int top_right_y; + int top_right_x; + int top_right_y; - int bottom_right_x; - int bottom_right_y; + int bottom_right_x; + int bottom_right_y; - int bottom_left_x; - int bottom_left_y; + int bottom_left_x; + int bottom_left_y; - border_radiuses() - { - top_left_x = 0; - top_left_y = 0; - top_right_x = 0; - top_right_y = 0; - bottom_right_x = 0; - bottom_right_y = 0; - bottom_left_x = 0; - bottom_left_y = 0; - } - border_radiuses(const border_radiuses& val) - { - top_left_x = val.top_left_x; - top_left_y = val.top_left_y; - top_right_x = val.top_right_x; - top_right_y = val.top_right_y; - bottom_right_x = val.bottom_right_x; - bottom_right_y = val.bottom_right_y; - bottom_left_x = val.bottom_left_x; - bottom_left_y = val.bottom_left_y; - } - border_radiuses& operator = (const border_radiuses& val) - { - top_left_x = val.top_left_x; - top_left_y = val.top_left_y; - top_right_x = val.top_right_x; - top_right_y = val.top_right_y; - bottom_right_x = val.bottom_right_x; - bottom_right_y = val.bottom_right_y; - bottom_left_x = val.bottom_left_x; - bottom_left_y = val.bottom_left_y; - return *this; - } - void operator += (const margins& mg) - { - top_left_x += mg.left; - top_left_y += mg.top; - top_right_x += mg.right; - top_right_y += mg.top; - bottom_right_x += mg.right; - bottom_right_y += mg.bottom; - bottom_left_x += mg.left; - bottom_left_y += mg.bottom; - fix_values(); - } - void operator -= (const margins& mg) - { - top_left_x -= mg.left; - top_left_y -= mg.top; - top_right_x -= mg.right; - top_right_y -= mg.top; - bottom_right_x -= mg.right; - bottom_right_y -= mg.bottom; - bottom_left_x -= mg.left; - bottom_left_y -= mg.bottom; - fix_values(); - } - void fix_values() - { - if (top_left_x < 0) top_left_x = 0; - if (top_left_y < 0) top_left_y = 0; - if (top_right_x < 0) top_right_x = 0; - if (top_right_y < 0) top_right_y = 0; - if (bottom_right_x < 0) bottom_right_x = 0; - if (bottom_right_y < 0) bottom_right_y = 0; - if (bottom_left_x < 0) bottom_left_x = 0; - if (bottom_left_y < 0) bottom_left_y = 0; - } - }; + border_radiuses() { + top_left_x = 0; + top_left_y = 0; + top_right_x = 0; + top_right_y = 0; + bottom_right_x = 0; + bottom_right_y = 0; + bottom_left_x = 0; + bottom_left_y = 0; + } + border_radiuses(const border_radiuses& val) { + top_left_x = val.top_left_x; + top_left_y = val.top_left_y; + top_right_x = val.top_right_x; + top_right_y = val.top_right_y; + bottom_right_x = val.bottom_right_x; + bottom_right_y = val.bottom_right_y; + bottom_left_x = val.bottom_left_x; + bottom_left_y = val.bottom_left_y; + } + border_radiuses& operator=(const border_radiuses& val) { + top_left_x = val.top_left_x; + top_left_y = val.top_left_y; + top_right_x = val.top_right_x; + top_right_y = val.top_right_y; + bottom_right_x = val.bottom_right_x; + bottom_right_y = val.bottom_right_y; + bottom_left_x = val.bottom_left_x; + bottom_left_y = val.bottom_left_y; + return *this; + } + void operator+=(const margins& mg) { + top_left_x += mg.left; + top_left_y += mg.top; + top_right_x += mg.right; + top_right_y += mg.top; + bottom_right_x += mg.right; + bottom_right_y += mg.bottom; + bottom_left_x += mg.left; + bottom_left_y += mg.bottom; + fix_values(); + } + void operator-=(const margins& mg) { + top_left_x -= mg.left; + top_left_y -= mg.top; + top_right_x -= mg.right; + top_right_y -= mg.top; + bottom_right_x -= mg.right; + bottom_right_y -= mg.bottom; + bottom_left_x -= mg.left; + bottom_left_y -= mg.bottom; + fix_values(); + } + void fix_values() { + if (top_left_x < 0) top_left_x = 0; + if (top_left_y < 0) top_left_y = 0; + if (top_right_x < 0) top_right_x = 0; + if (top_right_y < 0) top_right_y = 0; + if (bottom_right_x < 0) bottom_right_x = 0; + if (bottom_right_y < 0) bottom_right_y = 0; + if (bottom_left_x < 0) bottom_left_x = 0; + if (bottom_left_y < 0) bottom_left_y = 0; + } +}; - struct css_border_radius - { - css_length top_left_x; - css_length top_left_y; +struct css_border_radius { + css_length top_left_x; + css_length top_left_y; - css_length top_right_x; - css_length top_right_y; + css_length top_right_x; + css_length top_right_y; - css_length bottom_right_x; - css_length bottom_right_y; + css_length bottom_right_x; + css_length bottom_right_y; - css_length bottom_left_x; - css_length bottom_left_y; + css_length bottom_left_x; + css_length bottom_left_y; - css_border_radius() - { + css_border_radius() {} - } + css_border_radius(const css_border_radius& val) { + top_left_x = val.top_left_x; + top_left_y = val.top_left_y; + top_right_x = val.top_right_x; + top_right_y = val.top_right_y; + bottom_left_x = val.bottom_left_x; + bottom_left_y = val.bottom_left_y; + bottom_right_x = val.bottom_right_x; + bottom_right_y = val.bottom_right_y; + } - css_border_radius(const css_border_radius& val) - { - top_left_x = val.top_left_x; - top_left_y = val.top_left_y; - top_right_x = val.top_right_x; - top_right_y = val.top_right_y; - bottom_left_x = val.bottom_left_x; - bottom_left_y = val.bottom_left_y; - bottom_right_x = val.bottom_right_x; - bottom_right_y = val.bottom_right_y; - } + css_border_radius& operator=(const css_border_radius& val) { + top_left_x = val.top_left_x; + top_left_y = val.top_left_y; + top_right_x = val.top_right_x; + top_right_y = val.top_right_y; + bottom_left_x = val.bottom_left_x; + bottom_left_y = val.bottom_left_y; + bottom_right_x = val.bottom_right_x; + bottom_right_y = val.bottom_right_y; + return *this; + } + border_radiuses calc_percents(int width, int height) { + border_radiuses ret; + ret.bottom_left_x = bottom_left_x.calc_percent(width); + ret.bottom_left_y = bottom_left_y.calc_percent(height); + ret.top_left_x = top_left_x.calc_percent(width); + ret.top_left_y = top_left_y.calc_percent(height); + ret.top_right_x = top_right_x.calc_percent(width); + ret.top_right_y = top_right_y.calc_percent(height); + ret.bottom_right_x = bottom_right_x.calc_percent(width); + ret.bottom_right_y = bottom_right_y.calc_percent(height); + return ret; + } +}; - css_border_radius& operator=(const css_border_radius& val) - { - top_left_x = val.top_left_x; - top_left_y = val.top_left_y; - top_right_x = val.top_right_x; - top_right_y = val.top_right_y; - bottom_left_x = val.bottom_left_x; - bottom_left_y = val.bottom_left_y; - bottom_right_x = val.bottom_right_x; - bottom_right_y = val.bottom_right_y; - return *this; - } - border_radiuses calc_percents(int width, int height) - { - border_radiuses ret; - ret.bottom_left_x = bottom_left_x.calc_percent(width); - ret.bottom_left_y = bottom_left_y.calc_percent(height); - ret.top_left_x = top_left_x.calc_percent(width); - ret.top_left_y = top_left_y.calc_percent(height); - ret.top_right_x = top_right_x.calc_percent(width); - ret.top_right_y = top_right_y.calc_percent(height); - ret.bottom_right_x = bottom_right_x.calc_percent(width); - ret.bottom_right_y = bottom_right_y.calc_percent(height); - return ret; - } - }; +struct css_borders { + css_border left; + css_border top; + css_border right; + css_border bottom; + css_border_radius radius; - struct css_borders - { - css_border left; - css_border top; - css_border right; - css_border bottom; - css_border_radius radius; + css_borders() = default; - css_borders() = default; + bool is_visible() const { return left.width.val() != 0 || right.width.val() != 0 || top.width.val() != 0 || bottom.width.val() != 0; } - bool is_visible() const - { - return left.width.val() != 0 || right.width.val() != 0 || top.width.val() != 0 || bottom.width.val() != 0; - } + css_borders(const css_borders& val) { + left = val.left; + right = val.right; + top = val.top; + bottom = val.bottom; + radius = val.radius; + } - css_borders(const css_borders& val) - { - left = val.left; - right = val.right; - top = val.top; - bottom = val.bottom; - radius = val.radius; - } + css_borders& operator=(const css_borders& val) { + left = val.left; + right = val.right; + top = val.top; + bottom = val.bottom; + radius = val.radius; + return *this; + } +}; - css_borders& operator=(const css_borders& val) - { - left = val.left; - right = val.right; - top = val.top; - bottom = val.bottom; - radius = val.radius; - return *this; - } - }; +struct borders { + border left; + border top; + border right; + border bottom; + border_radiuses radius; - struct borders - { - border left; - border top; - border right; - border bottom; - border_radiuses radius; + borders() = default; - borders() = default; + borders(const borders& val) { + left = val.left; + right = val.right; + top = val.top; + bottom = val.bottom; + radius = val.radius; + } - borders(const borders& val) - { - left = val.left; - right = val.right; - top = val.top; - bottom = val.bottom; - radius = val.radius; - } + borders(const css_borders& val) { + left = val.left; + right = val.right; + top = val.top; + bottom = val.bottom; + } - borders(const css_borders& val) - { - left = val.left; - right = val.right; - top = val.top; - bottom = val.bottom; - } + bool is_visible() const { return left.width != 0 || right.width != 0 || top.width != 0 || bottom.width != 0; } - bool is_visible() const - { - return left.width != 0 || right.width != 0 || top.width != 0 || bottom.width != 0; - } + borders& operator=(const borders& val) { + left = val.left; + right = val.right; + top = val.top; + bottom = val.bottom; + radius = val.radius; + return *this; + } - borders& operator=(const borders& val) - { - left = val.left; - right = val.right; - top = val.top; - bottom = val.bottom; - radius = val.radius; - return *this; - } - - borders& operator=(const css_borders& val) - { - left = val.left; - right = val.right; - top = val.top; - bottom = val.bottom; - return *this; - } - }; -} + borders& operator=(const css_borders& val) { + left = val.left; + right = val.right; + top = val.top; + bottom = val.bottom; + return *this; + } +}; +} // namespace litehtml #endif // LH_BORDERS_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/box.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/box.h index 32c674e7a..481d7c6af 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/box.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/box.h @@ -1,120 +1,111 @@ #ifndef LH_BOX_H #define LH_BOX_H -namespace litehtml -{ - class html_tag; +namespace litehtml { +class html_tag; - enum box_type - { - box_block, - box_line - }; +enum box_type { box_block, box_line }; - class box - { - public: - typedef std::unique_ptr ptr; - typedef std::vector< box::ptr > vector; - protected: - int m_box_top; - int m_box_left; - int m_box_right; - public: - box(int top, int left, int right) - { - m_box_top = top; - m_box_left = left; - m_box_right = right; - } - virtual ~box() = default; +class box { + public: + typedef std::unique_ptr ptr; + typedef std::vector vector; - int bottom() const { return m_box_top + height(); } - int top() const { return m_box_top; } - int right() const { return m_box_left + width(); } - int left() const { return m_box_left; } + protected: + int m_box_top; + int m_box_left; + int m_box_right; - virtual litehtml::box_type get_type() const = 0; - virtual int height() const = 0; - virtual int width() const = 0; - virtual void add_element(const element::ptr &el) = 0; - virtual bool can_hold(const element::ptr &el, white_space ws) const = 0; - virtual void finish(bool last_box = false) = 0; - virtual bool is_empty() const = 0; - virtual int baseline() const = 0; - virtual void get_elements(elements_vector& els) = 0; - virtual int top_margin() const = 0; - virtual int bottom_margin() const = 0; - virtual void y_shift(int shift) = 0; - virtual void new_width(int left, int right, elements_vector& els) = 0; - }; + public: + box(int top, int left, int right) { + m_box_top = top; + m_box_left = left; + m_box_right = right; + } + virtual ~box() = default; - ////////////////////////////////////////////////////////////////////////// + int bottom() const { return m_box_top + height(); } + int top() const { return m_box_top; } + int right() const { return m_box_left + width(); } + int left() const { return m_box_left; } - class block_box : public box - { - element::ptr m_element; - public: - block_box(int top, int left, int right) : box(top, left, right) - { - m_element = nullptr; - } + virtual litehtml::box_type get_type() const = 0; + virtual int height() const = 0; + virtual int width() const = 0; + virtual void add_element(const element::ptr& el) = 0; + virtual bool can_hold(const element::ptr& el, white_space ws) const = 0; + virtual void finish(bool last_box = false) = 0; + virtual bool is_empty() const = 0; + virtual int baseline() const = 0; + virtual void get_elements(elements_vector& els) = 0; + virtual int top_margin() const = 0; + virtual int bottom_margin() const = 0; + virtual void y_shift(int shift) = 0; + virtual void new_width(int left, int right, elements_vector& els) = 0; +}; - litehtml::box_type get_type() const override; - int height() const override; - int width() const override; - void add_element(const element::ptr &el) override; - bool can_hold(const element::ptr &el, white_space ws) const override; - void finish(bool last_box = false) override; - bool is_empty() const override; - int baseline() const override; - void get_elements(elements_vector& els) override; - int top_margin() const override; - int bottom_margin() const override; - void y_shift(int shift) override; - void new_width(int left, int right, elements_vector& els) override; - }; +////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// +class block_box : public box { + element::ptr m_element; - class line_box : public box - { - elements_vector m_items; - int m_height; - int m_width; - int m_line_height; - font_metrics m_font_metrics; - int m_baseline; - text_align m_text_align; - public: - line_box(int top, int left, int right, int line_height, font_metrics& fm, text_align align) : box(top, left, right) - { - m_height = 0; - m_width = 0; - m_font_metrics = fm; - m_line_height = line_height; - m_baseline = 0; - m_text_align = align; - } + public: + block_box(int top, int left, int right) : box(top, left, right) { m_element = nullptr; } - litehtml::box_type get_type() const override; - int height() const override; - int width() const override; - void add_element(const element::ptr &el) override; - bool can_hold(const element::ptr &el, white_space ws) const override; - void finish(bool last_box = false) override; - bool is_empty() const override; - int baseline() const override; - void get_elements(elements_vector& els) override; - int top_margin() const override; - int bottom_margin() const override; - void y_shift(int shift) override; - void new_width(int left, int right, elements_vector& els) override; + litehtml::box_type get_type() const override; + int height() const override; + int width() const override; + void add_element(const element::ptr& el) override; + bool can_hold(const element::ptr& el, white_space ws) const override; + void finish(bool last_box = false) override; + bool is_empty() const override; + int baseline() const override; + void get_elements(elements_vector& els) override; + int top_margin() const override; + int bottom_margin() const override; + void y_shift(int shift) override; + void new_width(int left, int right, elements_vector& els) override; +}; - private: - bool have_last_space() const; - bool is_break_only() const; - }; -} +////////////////////////////////////////////////////////////////////////// + +class line_box : public box { + elements_vector m_items; + int m_height; + int m_width; + int m_line_height; + font_metrics m_font_metrics; + int m_baseline; + text_align m_text_align; + + public: + line_box(int top, int left, int right, int line_height, font_metrics& fm, text_align align) : box(top, left, right) { + m_height = 0; + m_width = 0; + m_font_metrics = fm; + m_line_height = line_height; + m_baseline = 0; + m_text_align = align; + } + + litehtml::box_type get_type() const override; + int height() const override; + int width() const override; + void add_element(const element::ptr& el) override; + bool can_hold(const element::ptr& el, white_space ws) const override; + void finish(bool last_box = false) override; + bool is_empty() const override; + int baseline() const override; + void get_elements(elements_vector& els) override; + int top_margin() const override; + int bottom_margin() const override; + void y_shift(int shift) override; + void new_width(int left, int right, elements_vector& els) override; + + private: + bool have_last_space() const; + bool is_break_only() const; +}; +} // namespace litehtml #endif // LH_BOX_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/codepoint.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/codepoint.h index 0bd7906b7..76e061f5a 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/codepoint.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/codepoint.h @@ -46,6 +46,6 @@ bool is_url_reserved_codepoint(litehtml::tchar_t c); // https://datatracker.ietf.org/doc/html/rfc3986#section-3.1 bool is_url_scheme_codepoint(litehtml::tchar_t c); -} // namespace litehtml +} // namespace litehtml -#endif // LITEHTML_CODEPOINT_H__ +#endif // LITEHTML_CODEPOINT_H__ diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/context.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/context.h index b6450f8f5..bbdbfaab2 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/context.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/context.h @@ -3,18 +3,14 @@ #include "stylesheet.h" -namespace litehtml -{ - class context - { - litehtml::css m_master_css; - public: - void load_master_stylesheet(const tchar_t* str); - litehtml::css& master_css() - { - return m_master_css; - } - }; -} +namespace litehtml { +class context { + litehtml::css m_master_css; + + public: + void load_master_stylesheet(const tchar_t* str); + litehtml::css& master_css() { return m_master_css; } +}; +} // namespace litehtml #endif // LH_CONTEXT_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_length.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_length.h index 13a3d77b7..57eb87579 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_length.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_length.h @@ -3,133 +3,107 @@ #include "types.h" -namespace litehtml -{ - class css_length - { - union - { - float m_value; - int m_predef; - }; - css_units m_units; - bool m_is_predefined; - public: - css_length(); - css_length(const css_length& val); +namespace litehtml { +class css_length { + union { + float m_value; + int m_predef; + }; + css_units m_units; + bool m_is_predefined; - css_length& operator=(const css_length& val); - css_length& operator=(float val); - bool is_predefined() const; - void predef(int val); - int predef() const; - void set_value(float val, css_units units); - float val() const; - css_units units() const; - int calc_percent(int width) const; - void fromString(const tstring& str, const tstring& predefs = _t(""), int defValue = 0); - }; + public: + css_length(); + css_length(const css_length& val); - // css_length inlines + css_length& operator=(const css_length& val); + css_length& operator=(float val); + bool is_predefined() const; + void predef(int val); + int predef() const; + void set_value(float val, css_units units); + float val() const; + css_units units() const; + int calc_percent(int width) const; + void fromString(const tstring& str, const tstring& predefs = _t(""), int defValue = 0); +}; - inline css_length::css_length() - { - m_value = 0; - m_predef = 0; - m_units = css_units_none; - m_is_predefined = false; - } +// css_length inlines - inline css_length::css_length(const css_length& val) - { - if(val.is_predefined()) - { - m_predef = val.m_predef; - } else - { - m_value = val.m_value; - } - m_units = val.m_units; - m_is_predefined = val.m_is_predefined; - } - - inline css_length& css_length::operator=(const css_length& val) - { - if(val.is_predefined()) - { - m_predef = val.m_predef; - } else - { - m_value = val.m_value; - } - m_units = val.m_units; - m_is_predefined = val.m_is_predefined; - return *this; - } - - inline css_length& css_length::operator=(float val) - { - m_value = val; - m_units = css_units_px; - m_is_predefined = false; - return *this; - } - - inline bool css_length::is_predefined() const - { - return m_is_predefined; - } - - inline void css_length::predef(int val) - { - m_predef = val; - m_is_predefined = true; - } - - inline int css_length::predef() const - { - if(m_is_predefined) - { - return m_predef; - } - return 0; - } - - inline void css_length::set_value(float val, css_units units) - { - m_value = val; - m_is_predefined = false; - m_units = units; - } - - inline float css_length::val() const - { - if(!m_is_predefined) - { - return m_value; - } - return 0; - } - - inline css_units css_length::units() const - { - return m_units; - } - - inline int css_length::calc_percent(int width) const - { - if(!is_predefined()) - { - if(units() == css_units_percentage) - { - return (int) ((double) width * (double) m_value / 100.0); - } else - { - return (int) val(); - } - } - return 0; - } +inline css_length::css_length() { + m_value = 0; + m_predef = 0; + m_units = css_units_none; + m_is_predefined = false; } +inline css_length::css_length(const css_length& val) { + if (val.is_predefined()) { + m_predef = val.m_predef; + } else { + m_value = val.m_value; + } + m_units = val.m_units; + m_is_predefined = val.m_is_predefined; +} + +inline css_length& css_length::operator=(const css_length& val) { + if (val.is_predefined()) { + m_predef = val.m_predef; + } else { + m_value = val.m_value; + } + m_units = val.m_units; + m_is_predefined = val.m_is_predefined; + return *this; +} + +inline css_length& css_length::operator=(float val) { + m_value = val; + m_units = css_units_px; + m_is_predefined = false; + return *this; +} + +inline bool css_length::is_predefined() const { return m_is_predefined; } + +inline void css_length::predef(int val) { + m_predef = val; + m_is_predefined = true; +} + +inline int css_length::predef() const { + if (m_is_predefined) { + return m_predef; + } + return 0; +} + +inline void css_length::set_value(float val, css_units units) { + m_value = val; + m_is_predefined = false; + m_units = units; +} + +inline float css_length::val() const { + if (!m_is_predefined) { + return m_value; + } + return 0; +} + +inline css_units css_length::units() const { return m_units; } + +inline int css_length::calc_percent(int width) const { + if (!is_predefined()) { + if (units() == css_units_percentage) { + return (int)((double)width * (double)m_value / 100.0); + } else { + return (int)val(); + } + } + return 0; +} +} // namespace litehtml + #endif // LH_CSS_LENGTH_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_margins.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_margins.h index def378a52..4f65c05b8 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_margins.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_margins.h @@ -3,34 +3,30 @@ #include "css_length.h" -namespace litehtml -{ - struct css_margins - { - css_length left; - css_length right; - css_length top; - css_length bottom; +namespace litehtml { +struct css_margins { + css_length left; + css_length right; + css_length top; + css_length bottom; - css_margins() = default; + css_margins() = default; - css_margins(const css_margins& val) - { - left = val.left; - right = val.right; - top = val.top; - bottom = val.bottom; - } + css_margins(const css_margins& val) { + left = val.left; + right = val.right; + top = val.top; + bottom = val.bottom; + } - css_margins& operator=(const css_margins& val) - { - left = val.left; - right = val.right; - top = val.top; - bottom = val.bottom; - return *this; - } - }; -} + css_margins& operator=(const css_margins& val) { + left = val.left; + right = val.right; + top = val.top; + bottom = val.bottom; + return *this; + } +}; +} // namespace litehtml #endif // LH_CSS_MARGINS_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_offsets.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_offsets.h index abeddfb6c..849889fe1 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_offsets.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_offsets.h @@ -3,34 +3,30 @@ #include "css_length.h" -namespace litehtml -{ - struct css_offsets - { - css_length left; - css_length top; - css_length right; - css_length bottom; +namespace litehtml { +struct css_offsets { + css_length left; + css_length top; + css_length right; + css_length bottom; - css_offsets() = default; + css_offsets() = default; - css_offsets(const css_offsets& val) - { - left = val.left; - top = val.top; - right = val.right; - bottom = val.bottom; - } + css_offsets(const css_offsets& val) { + left = val.left; + top = val.top; + right = val.right; + bottom = val.bottom; + } - css_offsets& operator=(const css_offsets& val) - { - left = val.left; - top = val.top; - right = val.right; - bottom = val.bottom; - return *this; - } - }; -} + css_offsets& operator=(const css_offsets& val) { + left = val.left; + top = val.top; + right = val.right; + bottom = val.bottom; + return *this; + } +}; +} // namespace litehtml #endif // LH_CSS_OFFSETS_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_position.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_position.h index 1f884121b..951c48e1d 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_position.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_position.h @@ -3,34 +3,30 @@ #include "css_length.h" -namespace litehtml -{ - struct css_position - { - css_length x; - css_length y; - css_length width; - css_length height; +namespace litehtml { +struct css_position { + css_length x; + css_length y; + css_length width; + css_length height; - css_position() = default; + css_position() = default; - css_position(const css_position& val) - { - x = val.x; - y = val.y; - width = val.width; - height = val.height; - } + css_position(const css_position& val) { + x = val.x; + y = val.y; + width = val.width; + height = val.height; + } - css_position& operator=(const css_position& val) - { - x = val.x; - y = val.y; - width = val.width; - height = val.height; - return *this; - } - }; -} + css_position& operator=(const css_position& val) { + x = val.x; + y = val.y; + width = val.width; + height = val.height; + return *this; + } +}; +} // namespace litehtml #endif // LH_CSS_POSITION_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_selector.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_selector.h index 45ba79498..9c96a278b 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_selector.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/css_selector.h @@ -1,276 +1,220 @@ #ifndef LH_CSS_SELECTOR_H #define LH_CSS_SELECTOR_H -#include "style.h" #include "media_query.h" +#include "style.h" -namespace litehtml -{ - ////////////////////////////////////////////////////////////////////////// +namespace litehtml { +////////////////////////////////////////////////////////////////////////// - struct selector_specificity - { - int a; - int b; - int c; - int d; +struct selector_specificity { + int a; + int b; + int c; + int d; - explicit selector_specificity(int va = 0, int vb = 0, int vc = 0, int vd = 0) - { - a = va; - b = vb; - c = vc; - d = vd; - } + explicit selector_specificity(int va = 0, int vb = 0, int vc = 0, int vd = 0) { + a = va; + b = vb; + c = vc; + d = vd; + } - void operator += (const selector_specificity& val) - { - a += val.a; - b += val.b; - c += val.c; - d += val.d; - } + void operator+=(const selector_specificity& val) { + a += val.a; + b += val.b; + c += val.c; + d += val.d; + } - bool operator==(const selector_specificity& val) const - { - if(a == val.a && b == val.b && c == val.c && d == val.d) - { - return true; - } - return false; - } + bool operator==(const selector_specificity& val) const { + if (a == val.a && b == val.b && c == val.c && d == val.d) { + return true; + } + return false; + } - bool operator!=(const selector_specificity& val) const - { - if(a != val.a || b != val.b || c != val.c || d != val.d) - { - return true; - } - return false; - } + bool operator!=(const selector_specificity& val) const { + if (a != val.a || b != val.b || c != val.c || d != val.d) { + return true; + } + return false; + } - bool operator > (const selector_specificity& val) const - { - if(a > val.a) - { - return true; - } else if(a < val.a) - { - return false; - } else - { - if(b > val.b) - { - return true; - } else if(b < val.b) - { - return false; - } else - { - if(c > val.c) - { - return true; - } else if(c < val.c) - { - return false; - } else - { - if(d > val.d) - { - return true; - } else if(d < val.d) - { - return false; - } - } - } - } - return false; - } + bool operator>(const selector_specificity& val) const { + if (a > val.a) { + return true; + } else if (a < val.a) { + return false; + } else { + if (b > val.b) { + return true; + } else if (b < val.b) { + return false; + } else { + if (c > val.c) { + return true; + } else if (c < val.c) { + return false; + } else { + if (d > val.d) { + return true; + } else if (d < val.d) { + return false; + } + } + } + } + return false; + } - bool operator >= (const selector_specificity& val) const - { - if((*this) == val) return true; - if((*this) > val) return true; - return false; - } + bool operator>=(const selector_specificity& val) const { + if ((*this) == val) return true; + if ((*this) > val) return true; + return false; + } - bool operator <= (const selector_specificity& val) const - { - if((*this) > val) - { - return false; - } - return true; - } + bool operator<=(const selector_specificity& val) const { + if ((*this) > val) { + return false; + } + return true; + } - bool operator < (const selector_specificity& val) const - { - if((*this) <= val && (*this) != val) - { - return true; - } - return false; - } + bool operator<(const selector_specificity& val) const { + if ((*this) <= val && (*this) != val) { + return true; + } + return false; + } +}; - }; +////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// +enum attr_select_condition { + select_exists, + select_equal, + select_contain_str, + select_start_str, + select_end_str, + select_pseudo_class, + select_pseudo_element, +}; - enum attr_select_condition - { - select_exists, - select_equal, - select_contain_str, - select_start_str, - select_end_str, - select_pseudo_class, - select_pseudo_element, - }; +////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// +struct css_attribute_selector { + typedef std::vector vector; - struct css_attribute_selector - { - typedef std::vector vector; + tstring attribute; + tstring val; + string_vector class_val; + attr_select_condition condition; - tstring attribute; - tstring val; - string_vector class_val; - attr_select_condition condition; + css_attribute_selector() { condition = select_exists; } +}; - css_attribute_selector() - { - condition = select_exists; - } - }; +////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// +class css_element_selector { + public: + tstring m_tag; + css_attribute_selector::vector m_attrs; - class css_element_selector - { - public: - tstring m_tag; - css_attribute_selector::vector m_attrs; - public: + public: + void parse(const tstring& txt); +}; - void parse(const tstring& txt); - }; +////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// +enum css_combinator { combinator_descendant, combinator_child, combinator_adjacent_sibling, combinator_general_sibling }; - enum css_combinator - { - combinator_descendant, - combinator_child, - combinator_adjacent_sibling, - combinator_general_sibling - }; +////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// +class css_selector { + public: + typedef std::shared_ptr ptr; + typedef std::vector vector; - class css_selector - { - public: - typedef std::shared_ptr ptr; - typedef std::vector vector; - public: - selector_specificity m_specificity; - css_element_selector m_right; - css_selector::ptr m_left; - css_combinator m_combinator; - style::ptr m_style; - int m_order; - media_query_list::ptr m_media_query; - public: - explicit css_selector(const media_query_list::ptr& media) - { - m_media_query = media; - m_combinator = combinator_descendant; - m_order = 0; - } + public: + selector_specificity m_specificity; + css_element_selector m_right; + css_selector::ptr m_left; + css_combinator m_combinator; + style::ptr m_style; + int m_order; + media_query_list::ptr m_media_query; - ~css_selector() = default; + public: + explicit css_selector(const media_query_list::ptr& media) { + m_media_query = media; + m_combinator = combinator_descendant; + m_order = 0; + } - css_selector(const css_selector& val) - { - m_right = val.m_right; - if(val.m_left) - { - m_left = std::make_shared(*val.m_left); - } else - { - m_left = nullptr; - } - m_combinator = val.m_combinator; - m_specificity = val.m_specificity; - m_order = val.m_order; - m_media_query = val.m_media_query; - } + ~css_selector() = default; - bool parse(const tstring& text); - void calc_specificity(); - bool is_media_valid() const; - void add_media_to_doc(document* doc) const; - }; + css_selector(const css_selector& val) { + m_right = val.m_right; + if (val.m_left) { + m_left = std::make_shared(*val.m_left); + } else { + m_left = nullptr; + } + m_combinator = val.m_combinator; + m_specificity = val.m_specificity; + m_order = val.m_order; + m_media_query = val.m_media_query; + } - inline bool css_selector::is_media_valid() const - { - if(!m_media_query) - { - return true; - } - return m_media_query->is_used(); - } + bool parse(const tstring& text); + void calc_specificity(); + bool is_media_valid() const; + void add_media_to_doc(document* doc) const; +}; - - ////////////////////////////////////////////////////////////////////////// - - inline bool operator > (const css_selector& v1, const css_selector& v2) - { - if(v1.m_specificity == v2.m_specificity) - { - return (v1.m_order > v2.m_order); - } - return (v1.m_specificity > v2.m_specificity); - } - - inline bool operator < (const css_selector& v1, const css_selector& v2) - { - if(v1.m_specificity == v2.m_specificity) - { - return (v1.m_order < v2.m_order); - } - return (v1.m_specificity < v2.m_specificity); - } - - inline bool operator >(const css_selector::ptr& v1, const css_selector::ptr& v2) - { - return (*v1 > *v2); - } - - inline bool operator < (const css_selector::ptr& v1, const css_selector::ptr& v2) - { - return (*v1 < *v2); - } - - ////////////////////////////////////////////////////////////////////////// - - class used_selector - { - public: - typedef std::unique_ptr ptr; - typedef std::vector vector; - - css_selector::ptr m_selector; - bool m_used; - - used_selector(const css_selector::ptr& selector, bool used) - { - m_used = used; - m_selector = selector; - } - }; +inline bool css_selector::is_media_valid() const { + if (!m_media_query) { + return true; + } + return m_media_query->is_used(); } +////////////////////////////////////////////////////////////////////////// + +inline bool operator>(const css_selector& v1, const css_selector& v2) { + if (v1.m_specificity == v2.m_specificity) { + return (v1.m_order > v2.m_order); + } + return (v1.m_specificity > v2.m_specificity); +} + +inline bool operator<(const css_selector& v1, const css_selector& v2) { + if (v1.m_specificity == v2.m_specificity) { + return (v1.m_order < v2.m_order); + } + return (v1.m_specificity < v2.m_specificity); +} + +inline bool operator>(const css_selector::ptr& v1, const css_selector::ptr& v2) { return (*v1 > *v2); } + +inline bool operator<(const css_selector::ptr& v1, const css_selector::ptr& v2) { return (*v1 < *v2); } + +////////////////////////////////////////////////////////////////////////// + +class used_selector { + public: + typedef std::unique_ptr ptr; + typedef std::vector vector; + + css_selector::ptr m_selector; + bool m_used; + + used_selector(const css_selector::ptr& selector, bool used) { + m_used = used; + m_selector = selector; + } +}; +} // namespace litehtml + #endif // LH_CSS_SELECTOR_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/document.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/document.h index 1fd8dab89..5cc03828f 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/document.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/document.h @@ -1,117 +1,105 @@ #ifndef LH_DOCUMENT_H #define LH_DOCUMENT_H +#include "context.h" #include "style.h" #include "types.h" -#include "context.h" -namespace litehtml -{ - struct css_text - { - typedef std::vector vector; +namespace litehtml { +struct css_text { + typedef std::vector vector; - tstring text; - tstring baseurl; - tstring media; - - css_text() = default; + tstring text; + tstring baseurl; + tstring media; - css_text(const tchar_t* txt, const tchar_t* url, const tchar_t* media_str) - { - text = txt ? txt : _t(""); - baseurl = url ? url : _t(""); - media = media_str ? media_str : _t(""); - } + css_text() = default; - css_text(const css_text& val) - { - text = val.text; - baseurl = val.baseurl; - media = val.media; - } - }; + css_text(const tchar_t* txt, const tchar_t* url, const tchar_t* media_str) { + text = txt ? txt : _t(""); + baseurl = url ? url : _t(""); + media = media_str ? media_str : _t(""); + } - class html_tag; + css_text(const css_text& val) { + text = val.text; + baseurl = val.baseurl; + media = val.media; + } +}; - class document : public std::enable_shared_from_this - { - public: - typedef std::shared_ptr ptr; - typedef std::weak_ptr weak_ptr; - private: - std::shared_ptr m_root; - document_container* m_container; - fonts_map m_fonts; - css_text::vector m_css; - litehtml::css m_styles; - litehtml::web_color m_def_color; - litehtml::context* m_context; - litehtml::size m_size; - position::vector m_fixed_boxes; - media_query_list::vector m_media_lists; - element::ptr m_over_element; - elements_vector m_tabular_elements; - media_features m_media; - tstring m_lang; - tstring m_culture; - public: - document(litehtml::document_container* objContainer, litehtml::context* ctx); - virtual ~document(); +class html_tag; - litehtml::document_container* container() { return m_container; } - uint_ptr get_font(const tchar_t* name, int size, const tchar_t* weight, const tchar_t* style, const tchar_t* decoration, font_metrics* fm); - int render(int max_width, render_type rt = render_all); - void draw(uint_ptr hdc, int x, int y, const position* clip); - web_color get_def_color() { return m_def_color; } - int cvt_units(const tchar_t* str, int fontSize, bool* is_percent = nullptr) const; - int cvt_units(css_length& val, int fontSize, int size = 0) const; - int width() const; - int height() const; - void add_stylesheet(const tchar_t* str, const tchar_t* baseurl, const tchar_t* media); - bool on_mouse_over(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); - bool on_lbutton_down(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); - bool on_lbutton_up(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); - bool on_mouse_leave(position::vector& redraw_boxes); - litehtml::element::ptr create_element(const tchar_t* tag_name, const string_map& attributes); - element::ptr root(); - void get_fixed_boxes(position::vector& fixed_boxes); - void add_fixed_box(const position& pos); - void add_media_list(const media_query_list::ptr& list); - bool media_changed(); - bool lang_changed(); - bool match_lang(const tstring & lang); - void add_tabular(const element::ptr& el); - element::const_ptr get_over_element() const { return m_over_element; } +class document : public std::enable_shared_from_this { + public: + typedef std::shared_ptr ptr; + typedef std::weak_ptr weak_ptr; - void append_children_from_string(element& parent, const tchar_t* str); - void append_children_from_utf8(element& parent, const char* str); + private: + std::shared_ptr m_root; + document_container* m_container; + fonts_map m_fonts; + css_text::vector m_css; + litehtml::css m_styles; + litehtml::web_color m_def_color; + litehtml::context* m_context; + litehtml::size m_size; + position::vector m_fixed_boxes; + media_query_list::vector m_media_lists; + element::ptr m_over_element; + elements_vector m_tabular_elements; + media_features m_media; + tstring m_lang; + tstring m_culture; - static litehtml::document::ptr createFromString(const tchar_t* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles = nullptr); - static litehtml::document::ptr createFromUTF8(const char* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles = nullptr); - - private: - litehtml::uint_ptr add_font(const tchar_t* name, int size, const tchar_t* weight, const tchar_t* style, const tchar_t* decoration, font_metrics* fm); + public: + document(litehtml::document_container* objContainer, litehtml::context* ctx); + virtual ~document(); - void create_node(void* gnode, elements_vector& elements, bool parseTextNode); - bool update_media_lists(const media_features& features); - void fix_tables_layout(); - void fix_table_children(element::ptr& el_ptr, style_display disp, const tchar_t* disp_str); - void fix_table_parent(element::ptr& el_ptr, style_display disp, const tchar_t* disp_str); - }; + litehtml::document_container* container() { return m_container; } + uint_ptr get_font(const tchar_t* name, int size, const tchar_t* weight, const tchar_t* style, const tchar_t* decoration, font_metrics* fm); + int render(int max_width, render_type rt = render_all); + void draw(uint_ptr hdc, int x, int y, const position* clip); + web_color get_def_color() { return m_def_color; } + int cvt_units(const tchar_t* str, int fontSize, bool* is_percent = nullptr) const; + int cvt_units(css_length& val, int fontSize, int size = 0) const; + int width() const; + int height() const; + void add_stylesheet(const tchar_t* str, const tchar_t* baseurl, const tchar_t* media); + bool on_mouse_over(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); + bool on_lbutton_down(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); + bool on_lbutton_up(int x, int y, int client_x, int client_y, position::vector& redraw_boxes); + bool on_mouse_leave(position::vector& redraw_boxes); + litehtml::element::ptr create_element(const tchar_t* tag_name, const string_map& attributes); + element::ptr root(); + void get_fixed_boxes(position::vector& fixed_boxes); + void add_fixed_box(const position& pos); + void add_media_list(const media_query_list::ptr& list); + bool media_changed(); + bool lang_changed(); + bool match_lang(const tstring& lang); + void add_tabular(const element::ptr& el); + element::const_ptr get_over_element() const { return m_over_element; } - inline element::ptr document::root() - { - return m_root; - } - inline void document::add_tabular(const element::ptr& el) - { - m_tabular_elements.push_back(el); - } - inline bool document::match_lang(const tstring & lang) - { - return lang == m_lang || lang == m_culture; - } -} + void append_children_from_string(element& parent, const tchar_t* str); + void append_children_from_utf8(element& parent, const char* str); + + static litehtml::document::ptr createFromString(const tchar_t* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles = nullptr); + static litehtml::document::ptr createFromUTF8(const char* str, litehtml::document_container* objPainter, litehtml::context* ctx, litehtml::css* user_styles = nullptr); + + private: + litehtml::uint_ptr add_font(const tchar_t* name, int size, const tchar_t* weight, const tchar_t* style, const tchar_t* decoration, font_metrics* fm); + + void create_node(void* gnode, elements_vector& elements, bool parseTextNode); + bool update_media_lists(const media_features& features); + void fix_tables_layout(); + void fix_table_children(element::ptr& el_ptr, style_display disp, const tchar_t* disp_str); + void fix_table_parent(element::ptr& el_ptr, style_display disp, const tchar_t* disp_str); +}; + +inline element::ptr document::root() { return m_root; } +inline void document::add_tabular(const element::ptr& el) { m_tabular_elements.push_back(el); } +inline bool document::match_lang(const tstring& lang) { return lang == m_lang || lang == m_culture; } +} // namespace litehtml #endif // LH_DOCUMENT_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_anchor.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_anchor.h index b33794c52..bd2d1b5c4 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_anchor.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_anchor.h @@ -3,16 +3,14 @@ #include "html_tag.h" -namespace litehtml -{ - class el_anchor : public html_tag - { - public: - explicit el_anchor(const std::shared_ptr& doc); +namespace litehtml { +class el_anchor : public html_tag { + public: + explicit el_anchor(const std::shared_ptr& doc); - void on_click() override; - void apply_stylesheet(const litehtml::css& stylesheet) override; - }; -} + void on_click() override; + void apply_stylesheet(const litehtml::css& stylesheet) override; +}; +} // namespace litehtml #endif // LH_EL_ANCHOR_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_base.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_base.h index d7efb8064..3253cbc39 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_base.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_base.h @@ -3,15 +3,13 @@ #include "html_tag.h" -namespace litehtml -{ - class el_base : public html_tag - { - public: - explicit el_base(const std::shared_ptr& doc); +namespace litehtml { +class el_base : public html_tag { + public: + explicit el_base(const std::shared_ptr& doc); - void parse_attributes() override; - }; -} + void parse_attributes() override; +}; +} // namespace litehtml #endif // LH_EL_BASE_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_before_after.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_before_after.h index b8ee89ebb..f09a87b9e 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_before_after.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_before_after.h @@ -3,38 +3,29 @@ #include "html_tag.h" -namespace litehtml -{ - class el_before_after_base : public html_tag - { - public: - el_before_after_base(const std::shared_ptr& doc, bool before); +namespace litehtml { +class el_before_after_base : public html_tag { + public: + el_before_after_base(const std::shared_ptr& doc, bool before); - void add_style(const litehtml::style& st) override; - void apply_stylesheet(const litehtml::css& stylesheet) override; - private: - void add_text(const tstring& txt); - void add_function(const tstring& fnc, const tstring& params); - static tstring convert_escape(const tchar_t* txt); - }; + void add_style(const litehtml::style& st) override; + void apply_stylesheet(const litehtml::css& stylesheet) override; - class el_before : public el_before_after_base - { - public: - explicit el_before(const std::shared_ptr& doc) : el_before_after_base(doc, true) - { + private: + void add_text(const tstring& txt); + void add_function(const tstring& fnc, const tstring& params); + static tstring convert_escape(const tchar_t* txt); +}; - } - }; +class el_before : public el_before_after_base { + public: + explicit el_before(const std::shared_ptr& doc) : el_before_after_base(doc, true) {} +}; - class el_after : public el_before_after_base - { - public: - explicit el_after(const std::shared_ptr& doc) : el_before_after_base(doc, false) - { - - } - }; -} +class el_after : public el_before_after_base { + public: + explicit el_after(const std::shared_ptr& doc) : el_before_after_base(doc, false) {} +}; +} // namespace litehtml #endif // LH_EL_BEFORE_AFTER_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_body.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_body.h index fb30e0c51..34a1df454 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_body.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_body.h @@ -3,15 +3,13 @@ #include "html_tag.h" -namespace litehtml -{ - class el_body : public html_tag - { - public: - explicit el_body(const std::shared_ptr& doc); +namespace litehtml { +class el_body : public html_tag { + public: + explicit el_body(const std::shared_ptr& doc); - bool is_body() const override; - }; -} + bool is_body() const override; +}; +} // namespace litehtml #endif // LH_EL_BODY_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_break.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_break.h index 81f38fec0..6fb1274c7 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_break.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_break.h @@ -3,15 +3,13 @@ #include "html_tag.h" -namespace litehtml -{ - class el_break : public html_tag - { - public: - explicit el_break(const std::shared_ptr& doc); +namespace litehtml { +class el_break : public html_tag { + public: + explicit el_break(const std::shared_ptr& doc); - bool is_break() const override; - }; -} + bool is_break() const override; +}; +} // namespace litehtml #endif // LH_EL_BREAK_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_cdata.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_cdata.h index a948c6201..7d450e7fc 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_cdata.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_cdata.h @@ -3,17 +3,16 @@ #include "html_tag.h" -namespace litehtml -{ - class el_cdata : public element - { - tstring m_text; - public: - explicit el_cdata(const std::shared_ptr& doc); +namespace litehtml { +class el_cdata : public element { + tstring m_text; - void get_text(tstring& text) override; - void set_data(const tchar_t* data) override; - }; -} + public: + explicit el_cdata(const std::shared_ptr& doc); + + void get_text(tstring& text) override; + void set_data(const tchar_t* data) override; +}; +} // namespace litehtml #endif // LH_EL_CDATA_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_comment.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_comment.h index f1fab3fda..30c3efcfc 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_comment.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_comment.h @@ -3,17 +3,16 @@ #include "html_tag.h" -namespace litehtml -{ - class el_comment : public element - { - tstring m_text; - public: - explicit el_comment(const std::shared_ptr& doc); +namespace litehtml { +class el_comment : public element { + tstring m_text; - void get_text(tstring& text) override; - void set_data(const tchar_t* data) override; - }; -} + public: + explicit el_comment(const std::shared_ptr& doc); + + void get_text(tstring& text) override; + void set_data(const tchar_t* data) override; +}; +} // namespace litehtml #endif // LH_EL_COMMENT_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_div.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_div.h index a2d031a32..433fdb692 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_div.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_div.h @@ -3,15 +3,13 @@ #include "html_tag.h" -namespace litehtml -{ - class el_div : public html_tag - { - public: - explicit el_div(const std::shared_ptr& doc); +namespace litehtml { +class el_div : public html_tag { + public: + explicit el_div(const std::shared_ptr& doc); - void parse_attributes() override; - }; -} + void parse_attributes() override; +}; +} // namespace litehtml #endif // LH_EL_DIV_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_font.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_font.h index ccb894512..e6f61a459 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_font.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_font.h @@ -3,15 +3,13 @@ #include "html_tag.h" -namespace litehtml -{ - class el_font : public html_tag - { - public: - explicit el_font(const std::shared_ptr& doc); +namespace litehtml { +class el_font : public html_tag { + public: + explicit el_font(const std::shared_ptr& doc); - void parse_attributes() override; - }; -} + void parse_attributes() override; +}; +} // namespace litehtml #endif // LH_EL_FONT_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_image.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_image.h index fa13d3c1d..4b3be1429 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_image.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_image.h @@ -3,26 +3,26 @@ #include "html_tag.h" -namespace litehtml -{ +namespace litehtml { - class el_image : public html_tag - { - tstring m_src; - public: - el_image(const std::shared_ptr& doc); - virtual ~el_image(void); +class el_image : public html_tag { + tstring m_src; - virtual int line_height() const override; - virtual bool is_replaced() const override; - virtual int render(int x, int y, int max_width, bool second_pass = false) override; - virtual void parse_attributes() override; - virtual void parse_styles(bool is_reparse = false) override; - virtual void draw(uint_ptr hdc, int x, int y, const position* clip) override; - virtual void get_content_size(size& sz, int max_width) override; - private: - int calc_max_height(int image_height); - }; -} + public: + el_image(const std::shared_ptr& doc); + virtual ~el_image(void); + + virtual int line_height() const override; + virtual bool is_replaced() const override; + virtual int render(int x, int y, int max_width, bool second_pass = false) override; + virtual void parse_attributes() override; + virtual void parse_styles(bool is_reparse = false) override; + virtual void draw(uint_ptr hdc, int x, int y, const position* clip) override; + virtual void get_content_size(size& sz, int max_width) override; + + private: + int calc_max_height(int image_height); +}; +} // namespace litehtml #endif // LH_EL_IMAGE_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_li.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_li.h index 4500465bc..3dd1f0f2d 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_li.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_li.h @@ -3,18 +3,16 @@ #include "html_tag.h" -namespace litehtml -{ - class el_li : public html_tag - { - public: - explicit el_li(const std::shared_ptr& doc); +namespace litehtml { +class el_li : public html_tag { + public: + explicit el_li(const std::shared_ptr& doc); - int render(int x, int y, int max_width, bool second_pass = false) override; + int render(int x, int y, int max_width, bool second_pass = false) override; - private: - bool m_index_initialized = false; - }; -} + private: + bool m_index_initialized = false; +}; +} // namespace litehtml #endif // LH_EL_LI_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_link.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_link.h index 0da3513dc..64fe5411b 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_link.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_link.h @@ -3,16 +3,14 @@ #include "html_tag.h" -namespace litehtml -{ - class el_link : public html_tag - { - public: - explicit el_link(const std::shared_ptr& doc); +namespace litehtml { +class el_link : public html_tag { + public: + explicit el_link(const std::shared_ptr& doc); - protected: - void parse_attributes() override; - }; -} + protected: + void parse_attributes() override; +}; +} // namespace litehtml #endif // LH_EL_LINK_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_para.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_para.h index 32ad53758..46cd356b6 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_para.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_para.h @@ -3,16 +3,13 @@ #include "html_tag.h" -namespace litehtml -{ - class el_para : public html_tag - { - public: - explicit el_para(const std::shared_ptr& doc); +namespace litehtml { +class el_para : public html_tag { + public: + explicit el_para(const std::shared_ptr& doc); - void parse_attributes() override; - - }; -} + void parse_attributes() override; +}; +} // namespace litehtml #endif // LH_EL_PARA_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_script.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_script.h index 66767957c..52ac8b81b 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_script.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_script.h @@ -3,18 +3,17 @@ #include "html_tag.h" -namespace litehtml -{ - class el_script : public element - { - tstring m_text; - public: - explicit el_script(const std::shared_ptr& doc); +namespace litehtml { +class el_script : public element { + tstring m_text; - void parse_attributes() override; - bool appendChild(const ptr &el) override; - const tchar_t* get_tagName() const override; - }; -} + public: + explicit el_script(const std::shared_ptr& doc); + + void parse_attributes() override; + bool appendChild(const ptr& el) override; + const tchar_t* get_tagName() const override; +}; +} // namespace litehtml #endif // LH_EL_SCRIPT_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_space.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_space.h index fba04bd89..94371e643 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_space.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_space.h @@ -1,19 +1,17 @@ #ifndef LH_EL_SPACE_H #define LH_EL_SPACE_H -#include "html_tag.h" #include "el_text.h" +#include "html_tag.h" -namespace litehtml -{ - class el_space : public el_text - { - public: - el_space(const tchar_t* text, const std::shared_ptr& doc); +namespace litehtml { +class el_space : public el_text { + public: + el_space(const tchar_t* text, const std::shared_ptr& doc); - bool is_white_space() const override; - bool is_break() const override; - }; -} + bool is_white_space() const override; + bool is_break() const override; +}; +} // namespace litehtml #endif // LH_EL_SPACE_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_style.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_style.h index 630268808..8c0fbaa89 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_style.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_style.h @@ -3,18 +3,17 @@ #include "html_tag.h" -namespace litehtml -{ - class el_style : public element - { - elements_vector m_children; - public: - explicit el_style(const std::shared_ptr& doc); +namespace litehtml { +class el_style : public element { + elements_vector m_children; - void parse_attributes() override; - bool appendChild(const ptr &el) override; - const tchar_t* get_tagName() const override; - }; -} + public: + explicit el_style(const std::shared_ptr& doc); + + void parse_attributes() override; + bool appendChild(const ptr& el) override; + const tchar_t* get_tagName() const override; +}; +} // namespace litehtml #endif // LH_EL_STYLE_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_table.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_table.h index ea9752142..f34b5bad2 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_table.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_table.h @@ -3,24 +3,20 @@ #include "html_tag.h" -namespace litehtml -{ - struct col_info - { - int width; - bool is_auto; - }; +namespace litehtml { +struct col_info { + int width; + bool is_auto; +}; +class el_table : public html_tag { + public: + explicit el_table(const std::shared_ptr& doc); - class el_table : public html_tag - { - public: - explicit el_table(const std::shared_ptr& doc); - - bool appendChild(const litehtml::element::ptr& el) override; - void parse_styles(bool is_reparse = false) override; - void parse_attributes() override; - }; -} + bool appendChild(const litehtml::element::ptr& el) override; + void parse_styles(bool is_reparse = false) override; + void parse_attributes() override; +}; +} // namespace litehtml #endif // LH_EL_TABLE_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_td.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_td.h index 03d21c1c7..73ebf2e5d 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_td.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_td.h @@ -3,15 +3,13 @@ #include "html_tag.h" -namespace litehtml -{ - class el_td : public html_tag - { - public: - explicit el_td(const std::shared_ptr& doc); +namespace litehtml { +class el_td : public html_tag { + public: + explicit el_td(const std::shared_ptr& doc); - void parse_attributes() override; - }; -} + void parse_attributes() override; +}; +} // namespace litehtml #endif // LH_EL_TD_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_text.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_text.h index 34771c6cb..fce1b7ebd 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_text.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_text.h @@ -3,35 +3,34 @@ #include "html_tag.h" -namespace litehtml -{ - class el_text : public element - { - protected: - tstring m_text; - tstring m_transformed_text; - size m_size; - text_transform m_text_transform; - bool m_use_transformed; - bool m_draw_spaces; - public: - el_text(const tchar_t* text, const std::shared_ptr& doc); +namespace litehtml { +class el_text : public element { + protected: + tstring m_text; + tstring m_transformed_text; + size m_size; + text_transform m_text_transform; + bool m_use_transformed; + bool m_draw_spaces; - void get_text(tstring& text) override; - const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) override; - void parse_styles(bool is_reparse) override; - int get_base_line() override; - void draw(uint_ptr hdc, int x, int y, const position* clip) override; - int line_height() const override; - uint_ptr get_font(font_metrics* fm = nullptr) override; - style_display get_display() const override; - white_space get_white_space() const override; - element_position get_element_position(css_offsets* offsets = nullptr) const override; - css_offsets get_css_offsets() const override; + public: + el_text(const tchar_t* text, const std::shared_ptr& doc); - protected: - void get_content_size(size& sz, int max_width) override; - }; -} + void get_text(tstring& text) override; + const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) override; + void parse_styles(bool is_reparse) override; + int get_base_line() override; + void draw(uint_ptr hdc, int x, int y, const position* clip) override; + int line_height() const override; + uint_ptr get_font(font_metrics* fm = nullptr) override; + style_display get_display() const override; + white_space get_white_space() const override; + element_position get_element_position(css_offsets* offsets = nullptr) const override; + css_offsets get_css_offsets() const override; + + protected: + void get_content_size(size& sz, int max_width) override; +}; +} // namespace litehtml #endif // LH_EL_TEXT_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_title.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_title.h index 201186a4a..911578e36 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_title.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_title.h @@ -3,16 +3,14 @@ #include "html_tag.h" -namespace litehtml -{ - class el_title : public html_tag - { - public: - explicit el_title(const std::shared_ptr& doc); +namespace litehtml { +class el_title : public html_tag { + public: + explicit el_title(const std::shared_ptr& doc); - protected: - void parse_attributes() override; - }; -} + protected: + void parse_attributes() override; +}; +} // namespace litehtml #endif // LH_EL_TITLE_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_tr.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_tr.h index 40a2f7038..0f813ca8f 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_tr.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/el_tr.h @@ -3,16 +3,14 @@ #include "html_tag.h" -namespace litehtml -{ - class el_tr : public html_tag - { - public: - explicit el_tr(const std::shared_ptr& doc); +namespace litehtml { +class el_tr : public html_tag { + public: + explicit el_tr(const std::shared_ptr& doc); - void parse_attributes() override; - void get_inline_boxes(position::vector& boxes) override; - }; -} + void parse_attributes() override; + void get_inline_boxes(position::vector& boxes) override; +}; +} // namespace litehtml #endif // LH_EL_TR_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/element.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/element.h index f2d68205e..bad1d89c0 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/element.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/element.h @@ -2,403 +2,297 @@ #define LH_ELEMENT_H #include -#include "stylesheet.h" + #include "css_offsets.h" +#include "stylesheet.h" -namespace litehtml -{ - class box; +namespace litehtml { +class box; - class element : public std::enable_shared_from_this - { - friend class block_box; - friend class line_box; - friend class html_tag; - friend class el_table; - friend class document; - public: - typedef std::shared_ptr ptr; - typedef std::shared_ptr const_ptr; - typedef std::weak_ptr weak_ptr; - protected: - std::weak_ptr m_parent; - std::weak_ptr m_doc; - litehtml::box* m_box; - elements_vector m_children; - position m_pos; - margins m_margins; - margins m_padding; - margins m_borders; - bool m_skip; - - virtual void select_all(const css_selector& selector, elements_vector& res); - public: - explicit element(const std::shared_ptr& doc); - virtual ~element() = default; +class element : public std::enable_shared_from_this { + friend class block_box; + friend class line_box; + friend class html_tag; + friend class el_table; + friend class document; - // returns refer to m_pos member; - position& get_position(); + public: + typedef std::shared_ptr ptr; + typedef std::shared_ptr const_ptr; + typedef std::weak_ptr weak_ptr; - int left() const; - int right() const; - int top() const; - int bottom() const; - int height() const; - int width() const; + protected: + std::weak_ptr m_parent; + std::weak_ptr m_doc; + litehtml::box* m_box; + elements_vector m_children; + position m_pos; + margins m_margins; + margins m_padding; + margins m_borders; + bool m_skip; - int content_margins_top() const; - int content_margins_bottom() const; - int content_margins_left() const; - int content_margins_right() const; - int content_margins_width() const; - int content_margins_height() const; + virtual void select_all(const css_selector& selector, elements_vector& res); - int margin_top() const; - int margin_bottom() const; - int margin_left() const; - int margin_right() const; - margins get_margins() const; + public: + explicit element(const std::shared_ptr& doc); + virtual ~element() = default; - int padding_top() const; - int padding_bottom() const; - int padding_left() const; - int padding_right() const; - margins get_paddings() const; + // returns refer to m_pos member; + position& get_position(); - int border_top() const; - int border_bottom() const; - int border_left() const; - int border_right() const; - margins get_borders() const; + int left() const; + int right() const; + int top() const; + int bottom() const; + int height() const; + int width() const; - bool in_normal_flow() const; - litehtml::web_color get_color(const tchar_t* prop_name, bool inherited, const litehtml::web_color& def_color = litehtml::web_color()); - bool is_inline_box() const; - position get_placement() const; - bool collapse_top_margin() const; - bool collapse_bottom_margin() const; - bool is_positioned() const; + int content_margins_top() const; + int content_margins_bottom() const; + int content_margins_left() const; + int content_margins_right() const; + int content_margins_width() const; + int content_margins_height() const; - bool skip() const; - void skip(bool val); - bool have_parent() const; - element::ptr parent() const; - void parent(const element::ptr& par); - bool is_visible() const; - int calc_width(int defVal) const; - int get_inline_shift_left(); - int get_inline_shift_right(); - void apply_relative_shift(int parent_width); + int margin_top() const; + int margin_bottom() const; + int margin_left() const; + int margin_right() const; + margins get_margins() const; - std::shared_ptr get_document() const; + int padding_top() const; + int padding_bottom() const; + int padding_left() const; + int padding_right() const; + margins get_paddings() const; - virtual elements_vector select_all(const tstring& selector); - virtual elements_vector select_all(const css_selector& selector); + int border_top() const; + int border_bottom() const; + int border_left() const; + int border_right() const; + margins get_borders() const; - virtual element::ptr select_one(const tstring& selector); - virtual element::ptr select_one(const css_selector& selector); + bool in_normal_flow() const; + litehtml::web_color get_color(const tchar_t* prop_name, bool inherited, const litehtml::web_color& def_color = litehtml::web_color()); + bool is_inline_box() const; + position get_placement() const; + bool collapse_top_margin() const; + bool collapse_bottom_margin() const; + bool is_positioned() const; - virtual int render(int x, int y, int max_width, bool second_pass = false); - virtual int render_inline(const ptr &container, int max_width); - virtual int place_element(const ptr &el, int max_width); - virtual void calc_outlines( int parent_width ); - virtual void calc_auto_margins(int parent_width); - virtual void apply_vertical_align(); - virtual bool fetch_positioned(); - virtual void render_positioned(render_type rt = render_all); + bool skip() const; + void skip(bool val); + bool have_parent() const; + element::ptr parent() const; + void parent(const element::ptr& par); + bool is_visible() const; + int calc_width(int defVal) const; + int get_inline_shift_left(); + int get_inline_shift_right(); + void apply_relative_shift(int parent_width); - virtual bool appendChild(const ptr &el); - virtual bool removeChild(const ptr &el); - virtual void clearRecursive(); + std::shared_ptr get_document() const; - virtual const tchar_t* get_tagName() const; - virtual void set_tagName(const tchar_t* tag); - virtual void set_data(const tchar_t* data); - virtual element_float get_float() const; - virtual vertical_align get_vertical_align() const; - virtual element_clear get_clear() const; - virtual size_t get_children_count() const; - virtual element::ptr get_child(int idx) const; - virtual overflow get_overflow() const; + virtual elements_vector select_all(const tstring& selector); + virtual elements_vector select_all(const css_selector& selector); - virtual css_length get_css_left() const; - virtual css_length get_css_right() const; - virtual css_length get_css_top() const; - virtual css_length get_css_bottom() const; - virtual css_offsets get_css_offsets() const; - virtual css_length get_css_width() const; - virtual void set_css_width(css_length& w); - virtual css_length get_css_height() const; + virtual element::ptr select_one(const tstring& selector); + virtual element::ptr select_one(const css_selector& selector); - virtual void set_attr(const tchar_t* name, const tchar_t* val); - virtual const tchar_t* get_attr(const tchar_t* name, const tchar_t* def = nullptr) const; - virtual void apply_stylesheet(const litehtml::css& stylesheet); - virtual void refresh_styles(); - virtual bool is_white_space() const; - virtual bool is_body() const; - virtual bool is_break() const; - virtual int get_base_line(); - virtual bool on_mouse_over(); - virtual bool on_mouse_leave(); - virtual bool on_lbutton_down(); - virtual bool on_lbutton_up(); - virtual void on_click(); - virtual bool find_styles_changes(position::vector& redraw_boxes, int x, int y); - virtual const tchar_t* get_cursor(); - virtual void init_font(); - virtual bool is_point_inside(int x, int y); - virtual bool set_pseudo_class(const tchar_t* pclass, bool add); - virtual bool set_class(const tchar_t* pclass, bool add); - virtual bool is_replaced() const; - virtual int line_height() const; - virtual white_space get_white_space() const; - virtual style_display get_display() const; - virtual visibility get_visibility() const; - virtual element_position get_element_position(css_offsets* offsets = nullptr) const; - virtual void get_inline_boxes(position::vector& boxes); - virtual void parse_styles(bool is_reparse = false); - virtual void draw(uint_ptr hdc, int x, int y, const position* clip); - virtual void draw_background( uint_ptr hdc, int x, int y, const position* clip ); - virtual const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr); - virtual uint_ptr get_font(font_metrics* fm = nullptr); - virtual int get_font_size() const; - virtual void get_text(tstring& text); - virtual void parse_attributes(); - virtual int select(const css_selector& selector, bool apply_pseudo = true); - virtual int select(const css_element_selector& selector, bool apply_pseudo = true); - virtual element::ptr find_ancestor(const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); - virtual bool is_ancestor(const ptr &el) const; - virtual element::ptr find_adjacent_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); - virtual element::ptr find_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); - virtual bool is_first_child_inline(const element::ptr& el) const; - virtual bool is_last_child_inline(const element::ptr& el); - virtual bool have_inline_child() const; - virtual void get_content_size(size& sz, int max_width); - virtual void init(); - virtual bool is_floats_holder() const; - virtual int get_floats_height(element_float el_float = float_none) const; - virtual int get_left_floats_height() const; - virtual int get_right_floats_height() const; - virtual int get_line_left(int y); - virtual int get_line_right(int y, int def_right); - virtual void get_line_left_right(int y, int def_right, int& ln_left, int& ln_right); - virtual void add_float(const ptr &el, int x, int y); - virtual void update_floats(int dy, const ptr &parent); - virtual void add_positioned(const ptr &el); - virtual int find_next_line_top(int top, int width, int def_right); - virtual int get_zindex() const; - virtual void draw_stacking_context(uint_ptr hdc, int x, int y, const position* clip, bool with_positioned); - virtual void draw_children( uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex ); - virtual bool is_nth_child(const element::ptr& el, int num, int off, bool of_type) const; - virtual bool is_nth_last_child(const element::ptr& el, int num, int off, bool of_type) const; - virtual bool is_only_child(const element::ptr& el, bool of_type) const; - virtual bool get_predefined_height(int& p_height) const; - virtual void calc_document_size(litehtml::size& sz, int x = 0, int y = 0); - virtual void get_redraw_box(litehtml::position& pos, int x = 0, int y = 0); - virtual void add_style(const litehtml::style& st); - virtual element::ptr get_element_by_point(int x, int y, int client_x, int client_y); - virtual element::ptr get_child_by_point(int x, int y, int client_x, int client_y, draw_flag flag, int zindex); - virtual const background* get_background(bool own_only = false); - }; + virtual int render(int x, int y, int max_width, bool second_pass = false); + virtual int render_inline(const ptr& container, int max_width); + virtual int place_element(const ptr& el, int max_width); + virtual void calc_outlines(int parent_width); + virtual void calc_auto_margins(int parent_width); + virtual void apply_vertical_align(); + virtual bool fetch_positioned(); + virtual void render_positioned(render_type rt = render_all); - ////////////////////////////////////////////////////////////////////////// - // INLINE FUNCTIONS // - ////////////////////////////////////////////////////////////////////////// + virtual bool appendChild(const ptr& el); + virtual bool removeChild(const ptr& el); + virtual void clearRecursive(); - inline int litehtml::element::right() const - { - return left() + width(); - } + virtual const tchar_t* get_tagName() const; + virtual void set_tagName(const tchar_t* tag); + virtual void set_data(const tchar_t* data); + virtual element_float get_float() const; + virtual vertical_align get_vertical_align() const; + virtual element_clear get_clear() const; + virtual size_t get_children_count() const; + virtual element::ptr get_child(int idx) const; + virtual overflow get_overflow() const; - inline int litehtml::element::left() const - { - return m_pos.left() - margin_left() - m_padding.left - m_borders.left; - } + virtual css_length get_css_left() const; + virtual css_length get_css_right() const; + virtual css_length get_css_top() const; + virtual css_length get_css_bottom() const; + virtual css_offsets get_css_offsets() const; + virtual css_length get_css_width() const; + virtual void set_css_width(css_length& w); + virtual css_length get_css_height() const; - inline int litehtml::element::top() const - { - return m_pos.top() - margin_top() - m_padding.top - m_borders.top; - } + virtual void set_attr(const tchar_t* name, const tchar_t* val); + virtual const tchar_t* get_attr(const tchar_t* name, const tchar_t* def = nullptr) const; + virtual void apply_stylesheet(const litehtml::css& stylesheet); + virtual void refresh_styles(); + virtual bool is_white_space() const; + virtual bool is_body() const; + virtual bool is_break() const; + virtual int get_base_line(); + virtual bool on_mouse_over(); + virtual bool on_mouse_leave(); + virtual bool on_lbutton_down(); + virtual bool on_lbutton_up(); + virtual void on_click(); + virtual bool find_styles_changes(position::vector& redraw_boxes, int x, int y); + virtual const tchar_t* get_cursor(); + virtual void init_font(); + virtual bool is_point_inside(int x, int y); + virtual bool set_pseudo_class(const tchar_t* pclass, bool add); + virtual bool set_class(const tchar_t* pclass, bool add); + virtual bool is_replaced() const; + virtual int line_height() const; + virtual white_space get_white_space() const; + virtual style_display get_display() const; + virtual visibility get_visibility() const; + virtual element_position get_element_position(css_offsets* offsets = nullptr) const; + virtual void get_inline_boxes(position::vector& boxes); + virtual void parse_styles(bool is_reparse = false); + virtual void draw(uint_ptr hdc, int x, int y, const position* clip); + virtual void draw_background(uint_ptr hdc, int x, int y, const position* clip); + virtual const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr); + virtual uint_ptr get_font(font_metrics* fm = nullptr); + virtual int get_font_size() const; + virtual void get_text(tstring& text); + virtual void parse_attributes(); + virtual int select(const css_selector& selector, bool apply_pseudo = true); + virtual int select(const css_element_selector& selector, bool apply_pseudo = true); + virtual element::ptr find_ancestor(const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); + virtual bool is_ancestor(const ptr& el) const; + virtual element::ptr find_adjacent_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); + virtual element::ptr find_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr); + virtual bool is_first_child_inline(const element::ptr& el) const; + virtual bool is_last_child_inline(const element::ptr& el); + virtual bool have_inline_child() const; + virtual void get_content_size(size& sz, int max_width); + virtual void init(); + virtual bool is_floats_holder() const; + virtual int get_floats_height(element_float el_float = float_none) const; + virtual int get_left_floats_height() const; + virtual int get_right_floats_height() const; + virtual int get_line_left(int y); + virtual int get_line_right(int y, int def_right); + virtual void get_line_left_right(int y, int def_right, int& ln_left, int& ln_right); + virtual void add_float(const ptr& el, int x, int y); + virtual void update_floats(int dy, const ptr& parent); + virtual void add_positioned(const ptr& el); + virtual int find_next_line_top(int top, int width, int def_right); + virtual int get_zindex() const; + virtual void draw_stacking_context(uint_ptr hdc, int x, int y, const position* clip, bool with_positioned); + virtual void draw_children(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex); + virtual bool is_nth_child(const element::ptr& el, int num, int off, bool of_type) const; + virtual bool is_nth_last_child(const element::ptr& el, int num, int off, bool of_type) const; + virtual bool is_only_child(const element::ptr& el, bool of_type) const; + virtual bool get_predefined_height(int& p_height) const; + virtual void calc_document_size(litehtml::size& sz, int x = 0, int y = 0); + virtual void get_redraw_box(litehtml::position& pos, int x = 0, int y = 0); + virtual void add_style(const litehtml::style& st); + virtual element::ptr get_element_by_point(int x, int y, int client_x, int client_y); + virtual element::ptr get_child_by_point(int x, int y, int client_x, int client_y, draw_flag flag, int zindex); + virtual const background* get_background(bool own_only = false); +}; - inline int litehtml::element::bottom() const - { - return top() + height(); - } +////////////////////////////////////////////////////////////////////////// +// INLINE FUNCTIONS // +////////////////////////////////////////////////////////////////////////// - inline int litehtml::element::height() const - { - return m_pos.height + margin_top() + margin_bottom() + m_padding.height() + m_borders.height(); - } +inline int litehtml::element::right() const { return left() + width(); } - inline int litehtml::element::width() const - { - return m_pos.width + margin_left() + margin_right() + m_padding.width() + m_borders.width(); - } +inline int litehtml::element::left() const { return m_pos.left() - margin_left() - m_padding.left - m_borders.left; } - inline int litehtml::element::content_margins_top() const - { - return margin_top() + m_padding.top + m_borders.top; - } +inline int litehtml::element::top() const { return m_pos.top() - margin_top() - m_padding.top - m_borders.top; } - inline int litehtml::element::content_margins_bottom() const - { - return margin_bottom() + m_padding.bottom + m_borders.bottom; - } +inline int litehtml::element::bottom() const { return top() + height(); } - inline int litehtml::element::content_margins_left() const - { - return margin_left() + m_padding.left + m_borders.left; - } +inline int litehtml::element::height() const { return m_pos.height + margin_top() + margin_bottom() + m_padding.height() + m_borders.height(); } - inline int litehtml::element::content_margins_right() const - { - return margin_right() + m_padding.right + m_borders.right; - } +inline int litehtml::element::width() const { return m_pos.width + margin_left() + margin_right() + m_padding.width() + m_borders.width(); } - inline int litehtml::element::content_margins_width() const - { - return content_margins_left() + content_margins_right(); - } +inline int litehtml::element::content_margins_top() const { return margin_top() + m_padding.top + m_borders.top; } - inline int litehtml::element::content_margins_height() const - { - return content_margins_top() + content_margins_bottom(); - } +inline int litehtml::element::content_margins_bottom() const { return margin_bottom() + m_padding.bottom + m_borders.bottom; } - inline litehtml::margins litehtml::element::get_paddings() const - { - return m_padding; - } +inline int litehtml::element::content_margins_left() const { return margin_left() + m_padding.left + m_borders.left; } - inline litehtml::margins litehtml::element::get_borders() const - { - return m_borders; - } +inline int litehtml::element::content_margins_right() const { return margin_right() + m_padding.right + m_borders.right; } - inline int litehtml::element::padding_top() const - { - return m_padding.top; - } +inline int litehtml::element::content_margins_width() const { return content_margins_left() + content_margins_right(); } - inline int litehtml::element::padding_bottom() const - { - return m_padding.bottom; - } +inline int litehtml::element::content_margins_height() const { return content_margins_top() + content_margins_bottom(); } - inline int litehtml::element::padding_left() const - { - return m_padding.left; - } +inline litehtml::margins litehtml::element::get_paddings() const { return m_padding; } - inline int litehtml::element::padding_right() const - { - return m_padding.right; - } +inline litehtml::margins litehtml::element::get_borders() const { return m_borders; } - inline bool litehtml::element::in_normal_flow() const - { - if(get_element_position() != element_position_absolute && get_display() != display_none) - { - return true; - } - return false; - } +inline int litehtml::element::padding_top() const { return m_padding.top; } - inline int litehtml::element::border_top() const - { - return m_borders.top; - } +inline int litehtml::element::padding_bottom() const { return m_padding.bottom; } - inline int litehtml::element::border_bottom() const - { - return m_borders.bottom; - } +inline int litehtml::element::padding_left() const { return m_padding.left; } - inline int litehtml::element::border_left() const - { - return m_borders.left; - } +inline int litehtml::element::padding_right() const { return m_padding.right; } - inline int litehtml::element::border_right() const - { - return m_borders.right; - } - - inline bool litehtml::element::skip() const - { - return m_skip; - } - - inline void litehtml::element::skip(bool val) - { - m_skip = val; - } - - inline bool litehtml::element::have_parent() const - { - return !m_parent.expired(); - } - - inline element::ptr litehtml::element::parent() const - { - return m_parent.lock(); - } - - inline void litehtml::element::parent(const element::ptr& par) - { - m_parent = par; - } - - inline int litehtml::element::margin_top() const - { - return m_margins.top; - } - - inline int litehtml::element::margin_bottom() const - { - return m_margins.bottom; - } - - inline int litehtml::element::margin_left() const - { - return m_margins.left; - } - - inline int litehtml::element::margin_right() const - { - return m_margins.right; - } - - inline litehtml::margins litehtml::element::get_margins() const - { - margins ret; - ret.left = margin_left(); - ret.right = margin_right(); - ret.top = margin_top(); - ret.bottom = margin_bottom(); - - return ret; - } - - inline bool litehtml::element::is_positioned() const - { - return (get_element_position() > element_position_static); - } - - inline bool litehtml::element::is_visible() const - { - return !(m_skip || get_display() == display_none || get_visibility() != visibility_visible); - } - - inline position& litehtml::element::get_position() - { - return m_pos; - } - - inline std::shared_ptr element::get_document() const - { - return m_doc.lock(); - } +inline bool litehtml::element::in_normal_flow() const { + if (get_element_position() != element_position_absolute && get_display() != display_none) { + return true; + } + return false; } +inline int litehtml::element::border_top() const { return m_borders.top; } + +inline int litehtml::element::border_bottom() const { return m_borders.bottom; } + +inline int litehtml::element::border_left() const { return m_borders.left; } + +inline int litehtml::element::border_right() const { return m_borders.right; } + +inline bool litehtml::element::skip() const { return m_skip; } + +inline void litehtml::element::skip(bool val) { m_skip = val; } + +inline bool litehtml::element::have_parent() const { return !m_parent.expired(); } + +inline element::ptr litehtml::element::parent() const { return m_parent.lock(); } + +inline void litehtml::element::parent(const element::ptr& par) { m_parent = par; } + +inline int litehtml::element::margin_top() const { return m_margins.top; } + +inline int litehtml::element::margin_bottom() const { return m_margins.bottom; } + +inline int litehtml::element::margin_left() const { return m_margins.left; } + +inline int litehtml::element::margin_right() const { return m_margins.right; } + +inline litehtml::margins litehtml::element::get_margins() const { + margins ret; + ret.left = margin_left(); + ret.right = margin_right(); + ret.top = margin_top(); + ret.bottom = margin_bottom(); + + return ret; +} + +inline bool litehtml::element::is_positioned() const { return (get_element_position() > element_position_static); } + +inline bool litehtml::element::is_visible() const { return !(m_skip || get_display() == display_none || get_visibility() != visibility_visible); } + +inline position& litehtml::element::get_position() { return m_pos; } + +inline std::shared_ptr element::get_document() const { return m_doc.lock(); } +} // namespace litehtml + #endif // LH_ELEMENT_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/html.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/html.h index 8bf9bedb3..680433006 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/html.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/html.h @@ -1,117 +1,104 @@ #ifndef LH_HTML_H #define LH_HTML_H -#include -#include #include -#include -#include -#include +#include + #include -#include +#include #include -#include "os_types.h" -#include "types.h" +#include +#include +#include +#include + #include "background.h" #include "borders.h" #include "html_tag.h" -#include "web_color.h" #include "media_query.h" +#include "os_types.h" +#include "types.h" +#include "web_color.h" -namespace litehtml -{ - struct list_marker - { - tstring image; - const tchar_t* baseurl; - list_style_type marker_type; - web_color color; - position pos; - int index; - uint_ptr font; - }; +namespace litehtml { +struct list_marker { + tstring image; + const tchar_t* baseurl; + list_style_type marker_type; + web_color color; + position pos; + int index; + uint_ptr font; +}; - // call back interface to draw text, images and other elements - class document_container - { - public: - virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) = 0; - virtual void delete_font(litehtml::uint_ptr hFont) = 0; - virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) = 0; - virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) = 0; - virtual int pt_to_px(int pt) const = 0; - virtual int get_default_font_size() const = 0; - virtual const litehtml::tchar_t* get_default_font_name() const = 0; - virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) = 0; - virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) = 0; - virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) = 0; - virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) = 0; - virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) = 0; +// call back interface to draw text, images and other elements +class document_container { + public: + virtual litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) = 0; + virtual void delete_font(litehtml::uint_ptr hFont) = 0; + virtual int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) = 0; + virtual void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) = 0; + virtual int pt_to_px(int pt) const = 0; + virtual int get_default_font_size() const = 0; + virtual const litehtml::tchar_t* get_default_font_name() const = 0; + virtual void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker& marker) = 0; + virtual void load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) = 0; + virtual void get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) = 0; + virtual void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint& bg) = 0; + virtual void draw_borders(litehtml::uint_ptr hdc, const litehtml::borders& borders, const litehtml::position& draw_pos, bool root) = 0; - virtual void set_caption(const litehtml::tchar_t* caption) = 0; - virtual void set_base_url(const litehtml::tchar_t* base_url) = 0; - virtual void link(const std::shared_ptr& doc, const litehtml::element::ptr& el) = 0; - virtual void on_anchor_click(const litehtml::tchar_t* url, const litehtml::element::ptr& el) = 0; - virtual void set_cursor(const litehtml::tchar_t* cursor) = 0; - virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) = 0; - virtual void import_css(litehtml::tstring& text, const litehtml::tstring& url, litehtml::tstring& baseurl) = 0; - virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) = 0; - virtual void del_clip() = 0; - virtual void get_client_rect(litehtml::position& client) const = 0; - virtual std::shared_ptr create_element(const litehtml::tchar_t *tag_name, - const litehtml::string_map &attributes, - const std::shared_ptr &doc) = 0; + virtual void set_caption(const litehtml::tchar_t* caption) = 0; + virtual void set_base_url(const litehtml::tchar_t* base_url) = 0; + virtual void link(const std::shared_ptr& doc, const litehtml::element::ptr& el) = 0; + virtual void on_anchor_click(const litehtml::tchar_t* url, const litehtml::element::ptr& el) = 0; + virtual void set_cursor(const litehtml::tchar_t* cursor) = 0; + virtual void transform_text(litehtml::tstring& text, litehtml::text_transform tt) = 0; + virtual void import_css(litehtml::tstring& text, const litehtml::tstring& url, litehtml::tstring& baseurl) = 0; + virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius, bool valid_x, bool valid_y) = 0; + virtual void del_clip() = 0; + virtual void get_client_rect(litehtml::position& client) const = 0; + virtual std::shared_ptr create_element(const litehtml::tchar_t* tag_name, const litehtml::string_map& attributes, const std::shared_ptr& doc) = 0; - virtual void get_media_features(litehtml::media_features& media) const = 0; - virtual void get_language(litehtml::tstring& language, litehtml::tstring & culture) const = 0; - virtual litehtml::tstring resolve_color(const litehtml::tstring& /*color*/) const { return litehtml::tstring(); } - virtual void split_text(const char* text, const std::function& on_word, const std::function& on_space); + virtual void get_media_features(litehtml::media_features& media) const = 0; + virtual void get_language(litehtml::tstring& language, litehtml::tstring& culture) const = 0; + virtual litehtml::tstring resolve_color(const litehtml::tstring& /*color*/) const { return litehtml::tstring(); } + virtual void split_text(const char* text, const std::function& on_word, const std::function& on_space); - protected: - ~document_container() = default; - }; + protected: + ~document_container() = default; +}; - void trim(tstring &s); - void lcase(tstring &s); - int value_index(const tstring& val, const tstring& strings, int defValue = -1, tchar_t delim = _t(';')); - bool value_in_list(const tstring& val, const tstring& strings, tchar_t delim = _t(';')); - tstring::size_type find_close_bracket(const tstring &s, tstring::size_type off, tchar_t open_b = _t('('), tchar_t close_b = _t(')')); - void split_string(const tstring& str, string_vector& tokens, const tstring& delims, const tstring& delims_preserve = _t(""), const tstring& quote = _t("\"")); - void join_string(tstring& str, const string_vector& tokens, const tstring& delims); - double t_strtod(const tchar_t* string, tchar_t** endPtr); +void trim(tstring& s); +void lcase(tstring& s); +int value_index(const tstring& val, const tstring& strings, int defValue = -1, tchar_t delim = _t(';')); +bool value_in_list(const tstring& val, const tstring& strings, tchar_t delim = _t(';')); +tstring::size_type find_close_bracket(const tstring& s, tstring::size_type off, tchar_t open_b = _t('('), tchar_t close_b = _t(')')); +void split_string(const tstring& str, string_vector& tokens, const tstring& delims, const tstring& delims_preserve = _t(""), const tstring& quote = _t("\"")); +void join_string(tstring& str, const string_vector& tokens, const tstring& delims); +double t_strtod(const tchar_t* string, tchar_t** endPtr); - int t_strcasecmp(const tchar_t *s1, const tchar_t *s2); - int t_strncasecmp(const tchar_t *s1, const tchar_t *s2, size_t n); - - inline int t_isdigit(int c) - { - return (c >= '0' && c <= '9'); - } - - inline int t_tolower(int c) - { - return (c >= 'A' && c <= 'Z' ? c + 'a' - 'A' : c); - } - - inline int round_f(float val) - { - int int_val = (int) val; - if(val - int_val >= 0.5) - { - int_val++; - } - return int_val; - } +int t_strcasecmp(const tchar_t* s1, const tchar_t* s2); +int t_strncasecmp(const tchar_t* s1, const tchar_t* s2, size_t n); - inline int round_d(double val) - { - int int_val = (int) val; - if(val - int_val >= 0.5) - { - int_val++; - } - return int_val; - } +inline int t_isdigit(int c) { return (c >= '0' && c <= '9'); } + +inline int t_tolower(int c) { return (c >= 'A' && c <= 'Z' ? c + 'a' - 'A' : c); } + +inline int round_f(float val) { + int int_val = (int)val; + if (val - int_val >= 0.5) { + int_val++; + } + return int_val; } +inline int round_d(double val) { + int int_val = (int)val; + if (val - int_val >= 0.5) { + int_val++; + } + return int_val; +} +} // namespace litehtml + #endif // LH_HTML_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/html_tag.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/html_tag.h index 86aa8452a..f772e55c8 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/html_tag.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/html_tag.h @@ -1,248 +1,238 @@ #ifndef LH_HTML_TAG_H #define LH_HTML_TAG_H +#include "background.h" +#include "borders.h" +#include "box.h" +#include "css_margins.h" +#include "css_selector.h" #include "element.h" #include "style.h" -#include "background.h" -#include "css_margins.h" -#include "borders.h" -#include "css_selector.h" #include "stylesheet.h" -#include "box.h" #include "table.h" -namespace litehtml -{ - struct line_context - { - int calculatedTop; - int top; - int left; - int right; +namespace litehtml { +struct line_context { + int calculatedTop; + int top; + int left; + int right; - int width() const - { - return right - left; - } - void fix_top() - { - calculatedTop = top; - } - }; + int width() const { return right - left; } + void fix_top() { calculatedTop = top; } +}; - class html_tag : public element - { - friend class elements_iterator; - friend class el_table; - friend class table_grid; - friend class block_box; - friend class line_box; - public: - typedef std::shared_ptr ptr; - protected: - box::vector m_boxes; - string_vector m_class_values; - tstring m_tag; - litehtml::style m_style; - string_map m_attrs; - vertical_align m_vertical_align; - text_align m_text_align; - style_display m_display; - list_style_type m_list_style_type; - list_style_position m_list_style_position; - white_space m_white_space; - element_float m_float; - element_clear m_clear; - floated_box::vector m_floats_left; - floated_box::vector m_floats_right; - elements_vector m_positioned; - background m_bg; - element_position m_el_position; - int m_line_height; - bool m_lh_predefined; - string_vector m_pseudo_classes; - used_selector::vector m_used_styles; - - uint_ptr m_font; - int m_font_size; - font_metrics m_font_metrics; +class html_tag : public element { + friend class elements_iterator; + friend class el_table; + friend class table_grid; + friend class block_box; + friend class line_box; - css_margins m_css_margins; - css_margins m_css_padding; - css_borders m_css_borders; - css_length m_css_width; - css_length m_css_height; - css_length m_css_min_width; - css_length m_css_min_height; - css_length m_css_max_width; - css_length m_css_max_height; - css_offsets m_css_offsets; - css_length m_css_text_indent; + public: + typedef std::shared_ptr ptr; - overflow m_overflow; - visibility m_visibility; - int m_z_index; - box_sizing m_box_sizing; + protected: + box::vector m_boxes; + string_vector m_class_values; + tstring m_tag; + litehtml::style m_style; + string_map m_attrs; + vertical_align m_vertical_align; + text_align m_text_align; + style_display m_display; + list_style_type m_list_style_type; + list_style_position m_list_style_position; + white_space m_white_space; + element_float m_float; + element_clear m_clear; + floated_box::vector m_floats_left; + floated_box::vector m_floats_right; + elements_vector m_positioned; + background m_bg; + element_position m_el_position; + int m_line_height; + bool m_lh_predefined; + string_vector m_pseudo_classes; + used_selector::vector m_used_styles; - int_int_cache m_cahe_line_left; - int_int_cache m_cahe_line_right; + uint_ptr m_font; + int m_font_size; + font_metrics m_font_metrics; - // data for table rendering - std::unique_ptr m_grid; - css_length m_css_border_spacing_x; - css_length m_css_border_spacing_y; - int m_border_spacing_x; - int m_border_spacing_y; - border_collapse m_border_collapse; + css_margins m_css_margins; + css_margins m_css_padding; + css_borders m_css_borders; + css_length m_css_width; + css_length m_css_height; + css_length m_css_min_width; + css_length m_css_min_height; + css_length m_css_max_width; + css_length m_css_max_height; + css_offsets m_css_offsets; + css_length m_css_text_indent; - void select_all(const css_selector& selector, elements_vector& res) override; + overflow m_overflow; + visibility m_visibility; + int m_z_index; + box_sizing m_box_sizing; - public: - explicit html_tag(const std::shared_ptr& doc); + int_int_cache m_cahe_line_left; + int_int_cache m_cahe_line_right; - /* render functions */ + // data for table rendering + std::unique_ptr m_grid; + css_length m_css_border_spacing_x; + css_length m_css_border_spacing_y; + int m_border_spacing_x; + int m_border_spacing_y; + border_collapse m_border_collapse; - int render(int x, int y, int max_width, bool second_pass = false) override; + void select_all(const css_selector& selector, elements_vector& res) override; - int render_inline(const element::ptr &container, int max_width) override; - int place_element(const element::ptr &el, int max_width) override; - bool fetch_positioned() override; - void render_positioned(render_type rt = render_all) override; + public: + explicit html_tag(const std::shared_ptr& doc); - int new_box(const element::ptr &el, int max_width, line_context& line_ctx); + /* render functions */ - int get_cleared_top(const element::ptr &el, int line_top) const; - int finish_last_box(bool end_of_render = false); + int render(int x, int y, int max_width, bool second_pass = false) override; - bool appendChild(const element::ptr &el) override; - bool removeChild(const element::ptr &el) override; - void clearRecursive() override; - const tchar_t* get_tagName() const override; - void set_tagName(const tchar_t* tag) override; - void set_data(const tchar_t* data) override; - element_float get_float() const override; - vertical_align get_vertical_align() const override; - css_length get_css_left() const override; - css_length get_css_right() const override; - css_length get_css_top() const override; - css_length get_css_bottom() const override; - css_length get_css_width() const override; - css_offsets get_css_offsets() const override; - void set_css_width(css_length& w) override; - css_length get_css_height() const override; - element_clear get_clear() const override; - size_t get_children_count() const override; - element::ptr get_child(int idx) const override; - element_position get_element_position(css_offsets* offsets = nullptr) const override; - overflow get_overflow() const override; + int render_inline(const element::ptr& container, int max_width) override; + int place_element(const element::ptr& el, int max_width) override; + bool fetch_positioned() override; + void render_positioned(render_type rt = render_all) override; - void set_attr(const tchar_t* name, const tchar_t* val) override; - const tchar_t* get_attr(const tchar_t* name, const tchar_t* def = nullptr) const override; - void apply_stylesheet(const litehtml::css& stylesheet) override; - void refresh_styles() override; + int new_box(const element::ptr& el, int max_width, line_context& line_ctx); - bool is_white_space() const override; - bool is_body() const override; - bool is_break() const override; - int get_base_line() override; - bool on_mouse_over() override; - bool on_mouse_leave() override; - bool on_lbutton_down() override; - bool on_lbutton_up() override; - void on_click() override; - bool find_styles_changes(position::vector& redraw_boxes, int x, int y) override; - const tchar_t* get_cursor() override; - void init_font() override; - bool set_pseudo_class(const tchar_t* pclass, bool add) override; - bool set_class(const tchar_t* pclass, bool add) override; - bool is_replaced() const override; - int line_height() const override; - white_space get_white_space() const override; - style_display get_display() const override; - visibility get_visibility() const override; - void parse_styles(bool is_reparse = false) override; - void draw(uint_ptr hdc, int x, int y, const position* clip) override; - void draw_background(uint_ptr hdc, int x, int y, const position* clip) override; + int get_cleared_top(const element::ptr& el, int line_top) const; + int finish_last_box(bool end_of_render = false); - const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) override; - uint_ptr get_font(font_metrics* fm = nullptr) override; - int get_font_size() const override; + bool appendChild(const element::ptr& el) override; + bool removeChild(const element::ptr& el) override; + void clearRecursive() override; + const tchar_t* get_tagName() const override; + void set_tagName(const tchar_t* tag) override; + void set_data(const tchar_t* data) override; + element_float get_float() const override; + vertical_align get_vertical_align() const override; + css_length get_css_left() const override; + css_length get_css_right() const override; + css_length get_css_top() const override; + css_length get_css_bottom() const override; + css_length get_css_width() const override; + css_offsets get_css_offsets() const override; + void set_css_width(css_length& w) override; + css_length get_css_height() const override; + element_clear get_clear() const override; + size_t get_children_count() const override; + element::ptr get_child(int idx) const override; + element_position get_element_position(css_offsets* offsets = nullptr) const override; + overflow get_overflow() const override; - elements_vector& children(); - void calc_outlines(int parent_width) override; - void calc_auto_margins(int parent_width) override; + void set_attr(const tchar_t* name, const tchar_t* val) override; + const tchar_t* get_attr(const tchar_t* name, const tchar_t* def = nullptr) const override; + void apply_stylesheet(const litehtml::css& stylesheet) override; + void refresh_styles() override; - int select(const css_selector& selector, bool apply_pseudo = true) override; - int select(const css_element_selector& selector, bool apply_pseudo = true) override; + bool is_white_space() const override; + bool is_body() const override; + bool is_break() const override; + int get_base_line() override; + bool on_mouse_over() override; + bool on_mouse_leave() override; + bool on_lbutton_down() override; + bool on_lbutton_up() override; + void on_click() override; + bool find_styles_changes(position::vector& redraw_boxes, int x, int y) override; + const tchar_t* get_cursor() override; + void init_font() override; + bool set_pseudo_class(const tchar_t* pclass, bool add) override; + bool set_class(const tchar_t* pclass, bool add) override; + bool is_replaced() const override; + int line_height() const override; + white_space get_white_space() const override; + style_display get_display() const override; + visibility get_visibility() const override; + void parse_styles(bool is_reparse = false) override; + void draw(uint_ptr hdc, int x, int y, const position* clip) override; + void draw_background(uint_ptr hdc, int x, int y, const position* clip) override; - elements_vector select_all(const tstring& selector) override; - elements_vector select_all(const css_selector& selector) override; + const tchar_t* get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = nullptr) override; + uint_ptr get_font(font_metrics* fm = nullptr) override; + int get_font_size() const override; - element::ptr select_one(const tstring& selector) override; - element::ptr select_one(const css_selector& selector) override; + elements_vector& children(); + void calc_outlines(int parent_width) override; + void calc_auto_margins(int parent_width) override; - element::ptr find_ancestor(const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; - element::ptr find_adjacent_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; - element::ptr find_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; - void get_text(tstring& text) override; - void parse_attributes() override; + int select(const css_selector& selector, bool apply_pseudo = true) override; + int select(const css_element_selector& selector, bool apply_pseudo = true) override; - bool is_first_child_inline(const element::ptr& el) const override; - bool is_last_child_inline(const element::ptr& el) override; - bool have_inline_child() const override; - void get_content_size(size& sz, int max_width) override; - void init() override; - void get_inline_boxes(position::vector& boxes) override; - bool is_floats_holder() const override; - int get_floats_height(element_float el_float = float_none) const override; - int get_left_floats_height() const override; - int get_right_floats_height() const override; - int get_line_left(int y) override; - int get_line_right(int y, int def_right) override; - void get_line_left_right(int y, int def_right, int& ln_left, int& ln_right) override; - void add_float(const element::ptr &el, int x, int y) override; - void update_floats(int dy, const element::ptr &parent) override; - void add_positioned(const element::ptr &el) override; - int find_next_line_top(int top, int width, int def_right) override; - void apply_vertical_align() override; - void draw_children(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex) override; - int get_zindex() const override; - void draw_stacking_context(uint_ptr hdc, int x, int y, const position* clip, bool with_positioned) override; - void calc_document_size(litehtml::size& sz, int x = 0, int y = 0) override; - void get_redraw_box(litehtml::position& pos, int x = 0, int y = 0) override; - void add_style(const litehtml::style& st) override; - element::ptr get_element_by_point(int x, int y, int client_x, int client_y) override; - element::ptr get_child_by_point(int x, int y, int client_x, int client_y, draw_flag flag, int zindex) override; + elements_vector select_all(const tstring& selector) override; + elements_vector select_all(const css_selector& selector) override; - bool is_nth_child(const element::ptr& el, int num, int off, bool of_type) const override; - bool is_nth_last_child(const element::ptr& el, int num, int off, bool of_type) const override; - bool is_only_child(const element::ptr& el, bool of_type) const override; - const background* get_background(bool own_only = false) override; + element::ptr select_one(const tstring& selector) override; + element::ptr select_one(const css_selector& selector) override; - protected: - void draw_children_box(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex); - void draw_children_table(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex); - int render_box(int x, int y, int max_width, bool second_pass = false); - int render_table(int x, int y, int max_width, bool second_pass = false); - int fix_line_width(int max_width, element_float flt); - void parse_background(); - void init_background_paint( position pos, background_paint &bg_paint, const background* bg ); - void draw_list_marker( uint_ptr hdc, const position &pos ); - tstring get_list_marker_text(int index); - static void parse_nth_child_params( const tstring& param, int &num, int &off ); - void remove_before_after(); - litehtml::element::ptr get_element_before(); - litehtml::element::ptr get_element_after(); - }; + element::ptr find_ancestor(const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; + element::ptr find_adjacent_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; + element::ptr find_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = nullptr) override; + void get_text(tstring& text) override; + void parse_attributes() override; - /************************************************************************/ - /* Inline Functions */ - /************************************************************************/ + bool is_first_child_inline(const element::ptr& el) const override; + bool is_last_child_inline(const element::ptr& el) override; + bool have_inline_child() const override; + void get_content_size(size& sz, int max_width) override; + void init() override; + void get_inline_boxes(position::vector& boxes) override; + bool is_floats_holder() const override; + int get_floats_height(element_float el_float = float_none) const override; + int get_left_floats_height() const override; + int get_right_floats_height() const override; + int get_line_left(int y) override; + int get_line_right(int y, int def_right) override; + void get_line_left_right(int y, int def_right, int& ln_left, int& ln_right) override; + void add_float(const element::ptr& el, int x, int y) override; + void update_floats(int dy, const element::ptr& parent) override; + void add_positioned(const element::ptr& el) override; + int find_next_line_top(int top, int width, int def_right) override; + void apply_vertical_align() override; + void draw_children(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex) override; + int get_zindex() const override; + void draw_stacking_context(uint_ptr hdc, int x, int y, const position* clip, bool with_positioned) override; + void calc_document_size(litehtml::size& sz, int x = 0, int y = 0) override; + void get_redraw_box(litehtml::position& pos, int x = 0, int y = 0) override; + void add_style(const litehtml::style& st) override; + element::ptr get_element_by_point(int x, int y, int client_x, int client_y) override; + element::ptr get_child_by_point(int x, int y, int client_x, int client_y, draw_flag flag, int zindex) override; - inline elements_vector& litehtml::html_tag::children() - { - return m_children; - } -} + bool is_nth_child(const element::ptr& el, int num, int off, bool of_type) const override; + bool is_nth_last_child(const element::ptr& el, int num, int off, bool of_type) const override; + bool is_only_child(const element::ptr& el, bool of_type) const override; + const background* get_background(bool own_only = false) override; + + protected: + void draw_children_box(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex); + void draw_children_table(uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex); + int render_box(int x, int y, int max_width, bool second_pass = false); + int render_table(int x, int y, int max_width, bool second_pass = false); + int fix_line_width(int max_width, element_float flt); + void parse_background(); + void init_background_paint(position pos, background_paint& bg_paint, const background* bg); + void draw_list_marker(uint_ptr hdc, const position& pos); + tstring get_list_marker_text(int index); + static void parse_nth_child_params(const tstring& param, int& num, int& off); + void remove_before_after(); + litehtml::element::ptr get_element_before(); + litehtml::element::ptr get_element_after(); +}; + +/************************************************************************/ +/* Inline Functions */ +/************************************************************************/ + +inline elements_vector& litehtml::html_tag::children() { return m_children; } +} // namespace litehtml #endif // LH_HTML_TAG_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/iterators.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/iterators.h index 4f4ae0f89..38aafd9d9 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/iterators.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/iterators.h @@ -3,87 +3,74 @@ #include "types.h" -namespace litehtml -{ - class element; +namespace litehtml { +class element; - class iterator_selector - { - public: - virtual bool select(const element::ptr& el) = 0; +class iterator_selector { + public: + virtual bool select(const element::ptr& el) = 0; - protected: - ~iterator_selector() = default; - }; + protected: + ~iterator_selector() = default; +}; - class elements_iterator - { - private: - struct stack_item - { - int idx; - element::ptr el; - stack_item() : idx(0) - { - } - stack_item(const stack_item& val) - { - idx = val.idx; - el = val.el; - } - stack_item(stack_item&& val) - { - idx = val.idx; - el = std::move(val.el); - } - }; +class elements_iterator { + private: + struct stack_item { + int idx; + element::ptr el; + stack_item() : idx(0) {} + stack_item(const stack_item& val) { + idx = val.idx; + el = val.el; + } + stack_item(stack_item&& val) { + idx = val.idx; + el = std::move(val.el); + } + }; - std::vector m_stack; - element::ptr m_el; - int m_idx; - iterator_selector* m_go_inside; - iterator_selector* m_select; - public: + std::vector m_stack; + element::ptr m_el; + int m_idx; + iterator_selector* m_go_inside; + iterator_selector* m_select; - elements_iterator(const element::ptr& el, iterator_selector* go_inside, iterator_selector* select) - { - m_el = el; - m_idx = -1; - m_go_inside = go_inside; - m_select = select; - } + public: + elements_iterator(const element::ptr& el, iterator_selector* go_inside, iterator_selector* select) { + m_el = el; + m_idx = -1; + m_go_inside = go_inside; + m_select = select; + } - ~elements_iterator() = default; + ~elements_iterator() = default; - element::ptr next(bool ret_parent = true); - - private: - void next_idx(); - }; + element::ptr next(bool ret_parent = true); - class go_inside_inline final : public iterator_selector - { - public: - bool select(const element::ptr& el) override; - }; + private: + void next_idx(); +}; - class go_inside_table final : public iterator_selector - { - public: - bool select(const element::ptr& el) override; - }; +class go_inside_inline final : public iterator_selector { + public: + bool select(const element::ptr& el) override; +}; - class table_rows_selector final : public iterator_selector - { - public: - bool select(const element::ptr& el) override; - }; +class go_inside_table final : public iterator_selector { + public: + bool select(const element::ptr& el) override; +}; - class table_cells_selector final : public iterator_selector - { - public: - bool select(const element::ptr& el) override; - }; -} +class table_rows_selector final : public iterator_selector { + public: + bool select(const element::ptr& el) override; +}; + +class table_cells_selector final : public iterator_selector { + public: + bool select(const element::ptr& el) override; +}; +} // namespace litehtml #endif // LH_ITERATORS_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/media_query.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/media_query.h index 6a81bcb32..6bbf0f499 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/media_query.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/media_query.h @@ -1,77 +1,69 @@ #ifndef LH_MEDIA_QUERY_H #define LH_MEDIA_QUERY_H -namespace litehtml -{ - struct media_query_expression - { - typedef std::vector vector; - media_feature feature; - int val; - int val2; - bool check_as_bool; - - media_query_expression() - { - check_as_bool = false; - feature = media_feature_none; - val = 0; - val2 = 0; - } +namespace litehtml { +struct media_query_expression { + typedef std::vector vector; + media_feature feature; + int val; + int val2; + bool check_as_bool; - bool check(const media_features& features) const; - }; + media_query_expression() { + check_as_bool = false; + feature = media_feature_none; + val = 0; + val2 = 0; + } - class media_query - { - public: - typedef std::shared_ptr ptr; - typedef std::vector vector; - private: - media_query_expression::vector m_expressions; - bool m_not; - media_type m_media_type; - public: - media_query(); - media_query(const media_query& val); + bool check(const media_features& features) const; +}; - static media_query::ptr create_from_string(const tstring& str, const std::shared_ptr& doc); - bool check(const media_features& features) const; - }; +class media_query { + public: + typedef std::shared_ptr ptr; + typedef std::vector vector; - class media_query_list - { - public: - typedef std::shared_ptr ptr; - typedef std::vector vector; - private: - media_query::vector m_queries; - bool m_is_used; - public: - media_query_list(); - media_query_list(const media_query_list& val); + private: + media_query_expression::vector m_expressions; + bool m_not; + media_type m_media_type; - static media_query_list::ptr create_from_string(const tstring& str, const std::shared_ptr& doc); - bool is_used() const; - bool apply_media_features(const media_features& features); // returns true if the m_is_used changed - }; + public: + media_query(); + media_query(const media_query& val); - inline media_query_list::media_query_list(const media_query_list& val) - { - m_is_used = val.m_is_used; - m_queries = val.m_queries; - } + static media_query::ptr create_from_string(const tstring& str, const std::shared_ptr& doc); + bool check(const media_features& features) const; +}; - inline media_query_list::media_query_list() - { - m_is_used = false; - } +class media_query_list { + public: + typedef std::shared_ptr ptr; + typedef std::vector vector; - inline bool media_query_list::is_used() const - { - return m_is_used; - } + private: + media_query::vector m_queries; + bool m_is_used; + public: + media_query_list(); + media_query_list(const media_query_list& val); + + static media_query_list::ptr create_from_string(const tstring& str, const std::shared_ptr& doc); + bool is_used() const; + bool apply_media_features(const media_features& features); // returns true if the m_is_used changed +}; + +inline media_query_list::media_query_list(const media_query_list& val) { + m_is_used = val.m_is_used; + m_queries = val.m_queries; } +inline media_query_list::media_query_list() { m_is_used = false; } + +inline bool media_query_list::is_used() const { return m_is_used; } + +} // namespace litehtml + #endif // LH_MEDIA_QUERY_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/num_cvt.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/num_cvt.h index 515e46d62..111f510e9 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/num_cvt.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/num_cvt.h @@ -2,18 +2,17 @@ #define NUM_CVT_H #include + #include "os_types.h" -namespace litehtml -{ - namespace num_cvt - { - litehtml::tstring to_latin_lower(int val); - litehtml::tstring to_latin_upper(int val); - litehtml::tstring to_greek_lower(int val); - litehtml::tstring to_roman_lower(int value); - litehtml::tstring to_roman_upper(int value); - } -} +namespace litehtml { +namespace num_cvt { +litehtml::tstring to_latin_lower(int val); +litehtml::tstring to_latin_upper(int val); +litehtml::tstring to_greek_lower(int val); +litehtml::tstring to_roman_lower(int value); +litehtml::tstring to_roman_upper(int value); +} // namespace num_cvt +} // namespace litehtml -#endif // NUM_CVT_H \ No newline at end of file +#endif // NUM_CVT_H \ No newline at end of file diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/os_types.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/os_types.h index 63d13149a..f9ef1cbd5 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/os_types.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/os_types.h @@ -1,12 +1,11 @@ #ifndef LH_OS_TYPES_H #define LH_OS_TYPES_H -#include #include +#include -namespace litehtml -{ -#if defined( WIN32 ) || defined( _WIN32 ) || defined( WINCE ) +namespace litehtml { +#if defined(WIN32) || defined(_WIN32) || defined(WINCE) // noexcept appeared since Visual Studio 2013 #if _MSC_VER < 1900 @@ -15,71 +14,71 @@ namespace litehtml #ifndef LITEHTML_UTF8 - typedef std::wstring tstring; - typedef wchar_t tchar_t; - typedef std::wstringstream tstringstream; +typedef std::wstring tstring; +typedef wchar_t tchar_t; +typedef std::wstringstream tstringstream; - #define _t(quote) L##quote +#define _t(quote) L##quote - #define t_strlen wcslen - #define t_strcmp wcscmp - #define t_strncmp wcsncmp - #define t_strtol wcstol - #define t_atoi _wtoi - #define t_itoa(value, buffer, size, radix) _itow_s(value, buffer, size, radix) - #define t_strstr wcsstr - #define t_isspace iswspace - #define t_to_string(val) std::to_wstring(val) +#define t_strlen wcslen +#define t_strcmp wcscmp +#define t_strncmp wcsncmp +#define t_strtol wcstol +#define t_atoi _wtoi +#define t_itoa(value, buffer, size, radix) _itow_s(value, buffer, size, radix) +#define t_strstr wcsstr +#define t_isspace iswspace +#define t_to_string(val) std::to_wstring(val) #else - typedef std::string tstring; - typedef char tchar_t; - typedef std::stringstream tstringstream; +typedef std::string tstring; +typedef char tchar_t; +typedef std::stringstream tstringstream; - #define _t(quote) quote +#define _t(quote) quote - #define t_strlen strlen - #define t_strcmp strcmp - #define t_strncmp strncmp - #define t_strtol strtol - #define t_atoi atoi - #define t_itoa(value, buffer, size, radix) _itoa_s(value, buffer, size, radix) - #define t_strstr strstr - #define t_isspace isspace - #define t_to_string(val) std::to_string(val) +#define t_strlen strlen +#define t_strcmp strcmp +#define t_strncmp strncmp +#define t_strtol strtol +#define t_atoi atoi +#define t_itoa(value, buffer, size, radix) _itoa_s(value, buffer, size, radix) +#define t_strstr strstr +#define t_isspace isspace +#define t_to_string(val) std::to_string(val) #endif - #ifdef _WIN64 - typedef unsigned __int64 uint_ptr; - #else - typedef unsigned int uint_ptr; - #endif +#ifdef _WIN64 +typedef unsigned __int64 uint_ptr; +#else +typedef unsigned int uint_ptr; +#endif #else - #define LITEHTML_UTF8 +#define LITEHTML_UTF8 - typedef std::string tstring; - typedef char tchar_t; - typedef std::uintptr_t uint_ptr; - typedef std::stringstream tstringstream; +typedef std::string tstring; +typedef char tchar_t; +typedef std::uintptr_t uint_ptr; +typedef std::stringstream tstringstream; - #define _t(quote) quote +#define _t(quote) quote - #define t_strlen strlen - #define t_strcmp strcmp - #define t_strncmp strncmp +#define t_strlen strlen +#define t_strcmp strcmp +#define t_strncmp strncmp - #define t_itoa(value, buffer, size, radix) snprintf(buffer, size, "%d", value) +#define t_itoa(value, buffer, size, radix) snprintf(buffer, size, "%d", value) - #define t_strtol strtol - #define t_atoi atoi - #define t_strstr strstr - #define t_isspace isspace - #define t_to_string(val) std::to_string(val) +#define t_strtol strtol +#define t_atoi atoi +#define t_strstr strstr +#define t_isspace isspace +#define t_to_string(val) std::to_string(val) #endif -} +} // namespace litehtml #endif // LH_OS_TYPES_H diff --git a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/style.h b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/style.h index 6e082806b..d9638e9b1 100644 --- a/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/style.h +++ b/src/libraries/qlitehtml/src/3rdparty/litehtml/include/litehtml/style.h @@ -1,95 +1,79 @@ #ifndef LH_STYLE_H #define LH_STYLE_H -#include "attributes.h" #include -namespace litehtml -{ - class property_value - { - public: - tstring m_value; - bool m_important; +#include "attributes.h" - property_value() - { - m_important = false; - } - property_value(const tchar_t* val, bool imp) - { - m_important = imp; - m_value = val; - } - property_value(const property_value& val) - { - m_value = val.m_value; - m_important = val.m_important; - } +namespace litehtml { +class property_value { + public: + tstring m_value; + bool m_important; - property_value& operator=(const property_value& val) - { - m_value = val.m_value; - m_important = val.m_important; - return *this; - } - }; + property_value() { m_important = false; } + property_value(const tchar_t* val, bool imp) { + m_important = imp; + m_value = val; + } + property_value(const property_value& val) { + m_value = val.m_value; + m_important = val.m_important; + } - typedef std::map props_map; + property_value& operator=(const property_value& val) { + m_value = val.m_value; + m_important = val.m_important; + return *this; + } +}; - class style - { - public: - typedef std::shared_ptr